JAVA经典问题算法大全之scala版

本文通过Scala语言重新实现了多个经典算法问题,包括斐波那契数列、鸡兔同笼问题、素数判断、水仙花数查找等。每道题目的解决思路清晰,附带详细代码注释。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

方法1:

object FirstRabit extends App{
  var (f, f1, f2) = (1L, 1L, 1L)
  val MONTH = 15L

  for(i<- 1L to MONTH){
    if(i <3) {
      f2 =1
    } else {
      f = f1 + f2;  f1 = f2;  f2 = f
    }
    println("第 " + i + " 个月兔子的对数为:" + f)
  }
}
方法2(使用递归方式):

object FirstRabit extends App{
  def func(x: Long): Long = {
    if(x== 1 ||x== 2) return 1L  else func(x - 1)+func(x - 2)
  }

  (1L to 15L).map{x=> println("2.第" + x + "个月兔子的对数为:"+func(x))}
}

/* 【程序2】

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

 */

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

 */

import java.lang.Math._

object SelectPrimeElement extends App{
  def isPrime(p: Int): Boolean = {
    for(i<-(2 to sqrt(p).toInt)) {
      if(p % i == 0) return false
    }
    true
  }

  val primeList = for(x<- (101 to 200) if isPrime(x)) yield x
  println("101 到200 之间的素数个数为:%s个".format(primeList.length))
  println("素数列表为:" + primeList.mkString(","))
}
/*【程序4】
 * 题目:打印出所有的"水仙花数(narcissus number)",所谓"水仙花数"是指一个三位数,
 * 其各位数字的立方的和等于该数本身。例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。

*/

object NarcissusNumber extends App {
  def isNarcissusNumber(x: Int): Boolean = {
    val f:Int = x/100
    val s:Int = x%100/10
    val t:Int = x%100%10
    if(f*f*f + s*s*s + t*t*t == x) true else false
  }
  println("所有水仙花数列表为:" + (100 to 999).filter(isNarcissusNumber).mkString(","))
}
/*【程序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的值,重复执行第一步。

*/

import scala.collection.mutable.ListBuffer

object ResolvePrimeFactor {
  var boolean = true
  var k = 2
  val primeListBuffer = ListBuffer[Int]()

  def main (args: Array[String]) {
    findPrimeFactor(90)
    println("90 = " + primeListBuffer.mkString(" * "))
  }

  def findPrimeFactor(n:Int):Unit = {
    while(k<=n && boolean) {
      n match {
        case n if(n == k) =>
          primeListBuffer.append(k)
          boolean=false
        case n if(n>k && n%k == 0) =>
          primeListBuffer.append(k)
          findPrimeFactor(n/k)
        case n if(n>k && n%k != 0) =>
          k+=1
          findPrimeFactor(n)
      }
    }
  }
}
/*【程序6】
* 题目:输入两个正整数m和n,求其最大公约数和最小公倍数。
* 在循环中,只要除数不等于0,用较大数除以较小的数,将小的一个数作为下一轮循环的大数,取得的余数作为下一轮循环的较小的数,如此循环直到较小的数的值为0,返回
* 较大的数,此数即为最大公约数,最小公倍数为两数之积除以最大公约数。
* */
object CommonDiviser {
  def main(args: Array[String]) {
    val (left, right) = (args(0).toInt, args(1).toInt)
    val MaxCommonDiviser = getCommonDiviser(left, right)
    println(args(0) + " 与 " + args(1) +" 的最大公约数为: " + MaxCommonDiviser)
    println(args(0) + " 与 " + args(1) +" 的最小公倍数为: " + (left*right)/MaxCommonDiviser)
  }

  def getCommonDiviser(left:Int, right:Int):Int = {
    var (l,r,result,tmp) = (left,right,0,0)
    if(l< r) {tmp = l; l = r; r = tmp }
    while(r>0) {
      tmp = l%r
      if(tmp != 0) {
        l=r
        r=tmp
      } else {
        result = r
        r=0
      }
    }
    result
  }
}
/*【程序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 的值。
*/
object SameNumberSum extends App {
  args.length match {
    case 2 =>
      val total = dataHandle(args(0).toInt, args(1).toInt)
      println(" = " + total)
    case _ =>
      println("请输入两个参数值!!")
      sys.exit(-1)
  }
  def dataHandle(number: Int, num:Int): Int = {
    var total = 0
    var b = 0
    for (i <- 1 to num) {
      b += number
      i match {
        case 5 => print(b)
        case _ => print(b + " + ")
      }
      total += b
      b *= 10
    }
    total
  }
}
/*【程序9】
题目:一个数如果恰好等于它的因子之和,这个数就称为 "完数 "。例如6=1+2+3.编程 找出1000以内的所有完数。

*/

object WangShu extends App {
  println("1到1000 的完数有:")
  val iList = for(i <- 1 to 1000 if isWangShu(i)) yield i
  println(iList.mkString(" "))

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值