03.Kotlin的分支判断和循环
Kotlin    2018-05-29 17:02:35    261    0    0
acme   Kotlin

    前面已经学到了Kotlin的数据类型,那么就要用这些数据类型来做些事情。

    一个程序,逃脱不了最基本的运行本质,那就是,分支判断和循环。一款程序无外乎从头到尾的执行,只是这个程序是否会停止,运行过程中的判断决定了程序运行的方向,循环可以让程序执行多次,和判断进行结合可以有更多的组合方式也会有更多的运行结果。

废话不说,直接上代码。


 

package cc.acme_me.kotlin
fun main(args: Array<String>) {
testWhile()
 testDoWhile()
 testFor()
 printNarcissisticNumber(100, 1000000)
}
/**
 * 水仙花数
 * 水仙花指三位数的数值,每个位上的数的立方之和等于这个数
 * 比如1^3 + 5^3 + 3^3 = 153
 */
fun testWhile() {
var num = 100
 while (num < 1000) {
 var a: Int = num.rem(10)//个位数
 var b = (num.rem(100) - a) / 10//十位数
 var c: Int = num / 100//百位数
 //判断是否符合条件,这个写法比较恶心,而且效率也有问题,初学这门语言,所以先写以后语言特性什么学会了再优化
 if (num == Math.pow(a.toDouble(), 3.0).toInt() + Math.pow(b.toDouble(), 3.0).toInt() + Math.pow(c.toDouble(), 3.0).toInt()) {
 println("$a^3 + $b^3 + $c^3 = $num")
 }
 num++
 }
}
/**
 * 四叶玫瑰数
 * 四叶玫瑰数四位数的数值,每个位上的数的四次方之和等于这个数
 * 比如1^4 + 6^4 + 3^4 + 4^4 = 1634
 */
fun testDoWhile() {
var num = 1000
//while循环和do while循环的区别是前者先进行判断,满足条件后进入循环体,后者与之相反,先运行循环体再进行判断是否满足条件进行一下次循环
 do {
 var a: Int = num.rem(10)//个位数
 var b = num.rem(100) / 10//十位数
 var c: Int = num.rem(1000) / 100//百位数
 var d: Int = num / 1000//千位数
 if (num == Math.pow(a.toDouble(), 4.0).toInt() + Math.pow(b.toDouble(), 4.0).toInt() + Math.pow(c.toDouble(), 4.0).toInt() + Math.pow(d.toDouble(), 4.0).toInt()) {
 println("$a^4 + $b^4 + $c^4 + $d^4 = $num")
 }
 num++
 } while (num < 10000)
}
/**
 * 五角星数
 * 五角星数是五位数的数值,每个位上的数的五次方之和等于这个数
 * 比如5^5 + 4^5 + 7^5 + 4^5 + 8^5 = 54748
 */
fun testFor() {
//声明一个数组并且赋值10000~99999闭区间(包含头尾)
 //下面的一条等价于 var num = 10000 until 100000 前闭后开区间(包含头不包含尾)
 var num = 10000..99999
//在这个情况下step 1可以省略 这个可以理解为i++ 如果递增是i+=2的时候可以写成step 2 以此类推
 for (i in num step 1) {
 var a: Int = i.rem(10)//个位数
 var b: Int = i.rem(100) / 10//十位数
 var c: Int = i.rem(1000) / 100//百位数
 var d: Int = i.rem(10000) / 1000//千位数
 var e: Int = i / 10000 //万位数
 if (i == Math.pow(a.toDouble(), 5.0).toInt() + Math.pow(b.toDouble(), 5.0).toInt() + Math.pow(c.toDouble(), 5.0).toInt() + Math.pow(d.toDouble(), 5.0).toInt() + Math.pow(e.toDouble(), 5.0).toInt()) {
 println("$a^5 + $b^5 + $c^5 + $d^5 + $e^5 = $i")
 }
 }
}
/**
 * 输入开始值和结束值,在这个范围内寻找水仙花数并且打印出来
 */
fun printNarcissisticNumber(startNum: Int, endNum: Int) {
//Kotlin的三目运算符 我这么做是确定最小的值作为起始位置
 var innerStartNum = if (endNum < startNum) endNum else startNum
 //和上面差不多的意思 决定大的值作为结束位置
 var innerEndNum = if (endNum > startNum) endNum else startNum
//上面两行代码等同于下面的判断,上面是为了用一下三目运算
 /*if (startNum > endNum) {
 inner_startNum = endNum
 inner_endNum = startNum
 } else {
 inner_endNum = endNum
 inner_startNum = startNum
 }*/
//最小的水仙花数是153,如果结束位置比这个小,那么这个程序就没有运行下去的意义了
 if (innerEndNum < 153) {
 println("您输入数值范围内没有水仙花数!")
 return
 }
//水仙花数至少要三位数,所以如果给了两位数,那么就要让它变到三位数
 //为什么放到153 因为已经满足上面的条件,说明数值范围内肯定是有水仙花数的,那么就从第一个水仙花数开始
 if (innerStartNum < 153) {
 innerStartNum = 153
 }
//记录取值范围内水仙花数的数量
 var numCount: Int = 0
//将取值范围变成数组然后开始循环
 var nums = innerStartNum..innerEndNum
//step 1 可以省略,因为默认就是1
 for (i in nums) {
 //指数是多少,因为三位水仙花是三次幂 四位是四次 五位是五次 以此类推
 var index: Int = i.toString().length
//下面这一段写得很恶心,而且效率真的很低,所以先这样写一下 将来再优化
 //十位数先计算出来
 var count: Int = (Math.pow(i.rem(10).toDouble(), index.toDouble())).toInt()
//这里是计算百位数到第二最高位
 var b = 2 until index
 for (j in b) {
 count += Math.pow(((i.rem(Math.pow(10.0, j.toDouble())).toInt() / Math.pow(10.0, (j - 1).toDouble()).toInt()).toDouble()), index.toDouble()).toInt()
 }
//最后在计算最高位
 count += Math.pow((i / Math.pow(10.0, (index - 1).toDouble()).toInt()).toDouble(), index.toDouble()).toInt()
if (i == count) {
 numCount++
 print("$i ")
 }
}
//这个存在的意义就是,如果取值范围内没有水仙花数,但是程序什么都没显示感觉比较难看,所以没有水仙花数提醒一下
 if (numCount == 0) {
 println("您输入数值范围内没有水仙花数!")
 }
}​

 

Pre: BBR

Next: 02.Kotlin的数据类型和简单函数

261
Table of content