Scala算法

来源:互联网 发布:乌鲁木齐 中亚 知乎 编辑:程序博客网 时间:2024/05/16 02:13

为了练习scala,特地从网上找来Java经典问题算法大全,用scala来实现,记录于此。

/*【程序1】
题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
1.程序分析: 兔子的规律为数列1,1,2,3,5,8,13,21....
*/

方法1:

[java] view plain copy
  1. object FirstRabit extends App{  
  2.   var (f, f1, f2) = (1L, 1L, 1L)  
  3.   val MONTH = 15L  
  4.   
  5.   for(i<- 1L to MONTH){  
  6.     if(i <3) {  
  7.       f2 =1  
  8.     } else {  
  9.       f = f1 + f2;  f1 = f2;  f2 = f  
  10.     }  
  11.     println("第 " + i + " 个月兔子的对数为:" + f)  
  12.   }  
  13. }  
方法2(使用递归方式):
[java] view plain copy
  1. object FirstRabit extends App{  
  2.   def func(x: Long): Long = {  
  3.     if(x== 1 ||x== 2return 1L  else func(x - 1)+func(x - 2)  
  4.   }  
  5.   
  6.   (1L to 15L).map{x=> println("2.第" + x + "个月兔子的对数为:"+func(x))}  
  7. }  

/* 【程序2】

 * 公鸡3元一只,母鸡2元一只,小鸡1元3只.有100元要买100只鸡,必须花光钱,怎样买

 */

[java] view plain copy
  1. object Buy100Chicken extends App{  
  2.   for(x<-(1 to 100)) {  
  3.     for(y<-(1 to 100)) {  
  4.       for(n<-(1 to 100)) {  
  5.         if((x+y+3*n == 100) && (3*x+2*y+n==100)) {  
  6.           println("公鸡:%s 只; 母鸡:%s 只; 小鸡: %s 只".format(x, y, 3*n))  
  7.         }  
  8.       }  
  9.     }  
  10.   }  
  11. }  
/**
 * 【程序3】
 * 题目:判断101-200之间有多少个素数,并输出所有素数。
 * 1.程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,
 * 则表明此数不是素数,反之是素数。

 */

[java] view plain copy
  1. import java.lang.Math._  
  2.   
  3. object SelectPrimeElement extends App{  
  4.   def isPrime(p: Int): Boolean = {  
  5.     for(i<-(2 to sqrt(p).toInt)) {  
  6.       if(p % i == 0return false  
  7.     }  
  8.     true  
  9.   }  
  10.   
  11.   val primeList = for(x<- (101 to 200if isPrime(x)) yield x  
  12.   println("101 到200 之间的素数个数为:%s个".format(primeList.length))  
  13.   println("素数列表为:" + primeList.mkString(","))  
  14. }  
/*【程序4】
 * 题目:打印出所有的"水仙花数(narcissus number)",所谓"水仙花数"是指一个三位数,
 * 其各位数字的立方的和等于该数本身。例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。

*/

[java] view plain copy
  1. object NarcissusNumber extends App {  
  2.   def isNarcissusNumber(x: Int): Boolean = {  
  3.     val f:Int = x/100  
  4.     val s:Int = x%100/10  
  5.     val t:Int = x%100%10  
  6.     if(f*f*f + s*s*s + t*t*t == x) true else false  
  7.   }  
  8.   println("所有水仙花数列表为:" + (100 to 999).filter(isNarcissusNumber).mkString(","))  
  9. }  
/*【程序5】
 * 题目:将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。
 * 程序分析:对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成:
 * (1)如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。
 * (2)如果k<n,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数n,重复执行第一步。
 * (3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步。

*/

[java] view plain copy
  1. import scala.collection.mutable.ListBuffer  
  2.   
  3. object ResolvePrimeFactor {  
  4.   var boolean = true  
  5.   var k = 2  
  6.   val primeListBuffer = ListBuffer[Int]()  
  7.   
  8.   def main (args: Array[String]) {  
  9.     findPrimeFactor(90)  
  10.     println("90 = " + primeListBuffer.mkString(" * "))  
  11.   }  
  12.   
  13.   def findPrimeFactor(n:Int):Unit = {  
  14.     while(k<=n && boolean) {  
  15.       n match {  
  16.         case n if(n == k) =>  
  17.           primeListBuffer.append(k)  
  18.           boolean=false  
  19.         case n if(n>k && n%k == 0) =>  
  20.           primeListBuffer.append(k)  
  21.           findPrimeFactor(n/k)  
  22.         case n if(n>k && n%k != 0) =>  
  23.           k+=1  
  24.           findPrimeFactor(n)  
  25.       }  
  26.     }  
  27.   }  
  28. }  
/*【程序6】
* 题目:输入两个正整数m和n,求其最大公约数和最小公倍数。
* 在循环中,只要除数不等于0,用较大数除以较小的数,将小的一个数作为下一轮循环的大数,取得的余数作为下一轮循环的较小的数,如此循环直到较小的数的值为0,返回
* 较大的数,此数即为最大公约数,最小公倍数为两数之积除以最大公约数。
* */
[java] view plain copy
  1. object CommonDiviser {  
  2.   def main(args: Array[String]) {  
  3.     val (left, right) = (args(0).toInt, args(1).toInt)  
  4.     val MaxCommonDiviser = getCommonDiviser(left, right)  
  5.     println(args(0) + " 与 " + args(1) +" 的最大公约数为: " + MaxCommonDiviser)  
  6.     println(args(0) + " 与 " + args(1) +" 的最小公倍数为: " + (left*right)/MaxCommonDiviser)  
  7.   }  
  8.   
  9.   def getCommonDiviser(left:Int, right:Int):Int = {  
  10.     var (l,r,result,tmp) = (left,right,0,0)  
  11.     if(l< r) {tmp = l; l = r; r = tmp }  
  12.     while(r>0) {  
  13.       tmp = l%r  
  14.       if(tmp != 0) {  
  15.         l=r  
  16.         r=tmp  
  17.       } else {  
  18.         result = r  
  19.         r=0  
  20.       }  
  21.     }  
  22.     result  
  23.   }  
  24. }  
/*【程序7】
* 题目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。
* 算法: 定义一个变量b, 赋初值为0;定义一变量sum, 赋初值为0,
* 进入循环后,将a + b 的值赋给b,将sum + b 的值赋给sum;
* 同时,将a 增加十倍, ++ i; 继续循环;
* 循环结束后,输出sum 的值。
*/
[java] view plain copy
  1. object SameNumberSum extends App {  
  2.   args.length match {  
  3.     case 2 =>  
  4.       val total = dataHandle(args(0).toInt, args(1).toInt)  
  5.       println(" = " + total)  
  6.     case _ =>  
  7.       println("请输入两个参数值!!")  
  8.       sys.exit(-1)  
  9.   }  
  10.   def dataHandle(number: Int, num:Int): Int = {  
  11.     var total = 0  
  12.     var b = 0  
  13.     for (i <- 1 to num) {  
  14.       b += number  
  15.       i match {  
  16.         case 5 => print(b)  
  17.         case _ => print(b + " + ")  
  18.       }  
  19.       total += b  
  20.       b *= 10  
  21.     }  
  22.     total  
  23.   }  
  24. }  
/*【程序9】
题目:一个数如果恰好等于它的因子之和,这个数就称为 "完数 "。例如6=1+2+3.编程 找出1000以内的所有完数。

*/

[java] view plain copy
  1. object WangShu extends App {  
  2.   println("1到1000 的完数有:")  
  3.   val iList = for(i <- 1 to 1000 if isWangShu(i)) yield i  
  4.   println(iList.mkString(" "))  
  5.   
  6.   def isWangShu(i:Int): Boolean = {  
  7.     var num = 0  
  8.     for (j <- 1 to i / 2) {  
  9.       if (i % j == 0) num += j  
  10.     }  
  11.     if (i==num) true else false  
  12.   }  
  13. }  
/*【程序10】
题目:一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,
求它在 第10次落地时,共经过多少米?第10次反弹多高?
*/
[java] view plain copy
  1. object FreeFall extends App {  
  2.   var distance:Double = 0D  
  3.   var high:Double = 100D  
  4.   for(i <- 1 to 10) {  
  5.     i match {  
  6.       case 1 => distance += high  
  7.       case _ => distance += high*2  
  8.     }  
  9.     high /= 2  
  10.   }  
  11.   println("distance = " + distance)  
  12.   println("high= " + high)  
  13. }  
/*【程序11】
* 题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
* 1.程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去 掉不满足条件的排列。
*/
[java] view plain copy
  1. import scala.collection.mutable.ListBuffer  
  2. object NumberRangeNotDuplicate extends App {  
  3.   val iListBuffer = ListBuffer[Int]()  
  4.   for (i<- 1 to 4) {  
  5.     for (j<- 1 to 4) {  
  6.       for (k<- 1 to 4) {  
  7.         if(i!=j && j!= k && i!=k) iListBuffer += i*100 + j*10 + k  
  8.       }  
  9.     }  
  10.   }  
  11.   println("能组成互不相同且无重复数字的三位数有: " + iListBuffer.length)  
  12.   println("分别为: " + iListBuffer.mkString(" "))