前面已经学到了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("您输入数值范围内没有水仙花数!") } }