在scala中迭代while循环

Jer*_*emy 0 scala

我正在尝试编写一个程序,将一个数字转换为它的字符串等价物.IE 987,654,321 =九十八七百万六五十四数千三百二十一.我从控制台读取值,我想迭代从i = 0到string.length的while循环

   var s = "987654321"
   var characters = s.toString;
   var i = 0;
   while(i < characters.length){
     do something
   }
Run Code Online (Sandbox Code Playgroud)

我的代码如下

    object project1 {
      def main(args: Array[String]) {
        println("Enter a number")
        val s = Console.readLine

        println(eval(s));
      }

      def tens(c: Char) : String = ( 
        if (c.toInt == 9){
          return "Ninety";
        } else if (c.toInt == 8){
          return "Eighty";
        } else if(c.toInt == 7){
          return "Seventy";
        } else if(c.toInt == 6){
          return "Sixty";
        } else if(c.toInt == 5){
          return "Fifty";
        } else if(c.toInt == 4){
          return "Fourty";
        } else if(c.toInt == 3){
          return "Thirty";
        } else if(c.toInt == 2){
          return "Twenty";
        } else{
          return "";
        }
  )

      def everyThingElse(c : Char): String = (
        if (c.toInt == 9){
          return "Nine";
        } else if (c.toInt == 8){
          return "Eight";
        } else if(c.toInt == 7){
          return "Seven";
        } else if(c.toInt  == 6){
          return "Six";
        } else if(c.toInt  == 5){
          return "Five";
        } else if(c.toInt  == 4){
          return "Four";
        } else if(c.toInt  == 3){
          return "Three";
        } else if(c.toInt  == 2){
          return "Two";
        } else if(c.toInt  == 1){
          return "One";
        } else{
          return "";
        }
      );

      def eval(s: String): String = {
        val characters = s.toCharArray;
        var word = "";
        var i = 0;
        while( i < characters.length ){
          if((i == 14) || (i == 11) || (i == 8) || (i == 5) || (i == 2)){
            word = word + everyThingElse(characters(i));
            word = word + " Hundred ";
            i += 1;
          } else if ((i == 13) || (i == 10) || (i == 7) || (i == 4) || (i == 1)){
            if(characters(i).toInt != 1){
              word = word + tens(characters(i));
              i += 1;
            } else{
              i += 1;
              if(characters(i).toInt == 9){
                word = word + " Nineteen ";
              } else if(characters(i).toInt == 8){
                word = word + " Eighteen ";
              } else if(characters(i).toInt ==7){
                word = word + " Seventeen ";
              } else if(characters(i).toInt == 6){
                word = word + " Sixteen ";
              } else if(characters(i).toInt == 5){
                word = word + " Fifteen ";
              } else if(characters(i).toInt == 4){
                word = word + " Fourteen ";
              } else if(characters(i).toInt == 3){
                word = word + " Thirdteen ";
              } else if(characters(i).toInt == 2){
                word = word + " Twelve ";
              } else if(characters(i).toInt == 1){
                word = word + " Ten ";
              }
              i += 1;
            }
          } else if (i == 9){
            word = word + everyThingElse(characters(i));
            word = word + " Billion ";
            i += 1;
          } else if(i == 6){
            word = word + everyThingElse(characters(i));
            word = word + " Million ";
            i += 1;
          } else if (i == 12){
            word = word + everyThingElse(characters(i));
            word = word + " Trillion ";
            i += 1;
          } else if (i == 0){
            word = word + everyThingElse(characters(i));
            i += 1;
          }
        }
      }
    }
Run Code Online (Sandbox Code Playgroud)

Rex*_*err 7

我决定将这个作为输出选项很有趣,所以我创建了:

object Longhand {
  val small = (
    " one two three four five six seven eight nine ten eleven twelve " +
    "thirteen fourteen fifteen sixteen seventeen eighteen nineteen"
  ).split(' ')

  val mid = "twen thir for fif six seven eigh nine".split(' ').map(_ + "ty")

  lazy val big: Stream[String] = {
    Stream("", "thousand") #::: 
    "m b tr quadr quint sext sept oct non dec".split(' ').map(_+"illion").toStream #:::
    big.drop(1).map(_ + "-decillion")
  }

  def duo(n: Int) = {
    if (n >= 20) List(mid(n/10 - 2), small(n % 10)).filterNot(_.isEmpty)
    else List(small(n)).filterNot(_.isEmpty)
  }

  def trio(n: Int, and: Boolean = false) = {
    val tens = duo(n % 100) match {
      case Nil => Nil
      case x => if (and) "and" :: x else x
    }
    List(small(n/100)).filterNot(_.isEmpty).map(_ + " hundred") ::: tens
  }

  def triples(s: String) = s.reverse.grouped(3).map(_.reverse.toInt).toList

  def apply(s: String): String = {
    val and = (s.length>2) #:: Stream.continually(false)
    val tri = (triples(s) zip and).map{ case (s,a) => trio(s,a) }
    val all = (tri zip big).collect{ case (t,b) if !t.isEmpty => t :+ b }
    all.reverse.flatten.filterNot(_.isEmpty).mkString(" ")
  }
  def apply(l: Long): String = if (l<0) "minus "+apply(-l) else apply(l.toString)
  def apply(b: BigInt): String = if (b<0) "minus "+apply(-b) else apply(b.toString)
}
Run Code Online (Sandbox Code Playgroud)

它处理任意长度的字符串.它拥有一切和厨房水槽(更适合代码高尔夫而不是教学目的),但也许你可以从中得到一些指示.特别是,你应该尝试使用列表(数组,向量,某些东西),以避免一遍又一遍地重复自己....

有没有想过最大的unsigned long long(Long)是什么写的?

scala> Longhand(BigInt(2).pow(64)-1)
res32: String = eighteen quintillion four hundred forty six quadrillion
  seven hundred forty four trillion seventy three billion seven hundred nine million
  five hundred fifty one thousand six hundred and fifteen
Run Code Online (Sandbox Code Playgroud)

编辑:等等,如果你想解决反问题怎么办?只需在应用之后和结束括号之前插入:

val bigset = big.take(12).filterNot(_.isEmpty).toSet
val smallset = small.filterNot(_.isEmpty).toSet
val midset = mid.toSet
val valid = (bigset ++ smallset ++ mid) + "hundred"
val bignum = Iterator.iterate(BigInt(1000))(_ * 1000).take(11).toArray

def unapply(text: String): Option[BigInt] = {
  val bits = text.toLowerCase.trim.split(" +|-").filter(x => !x.isEmpty && x!="and")
  if (!bits.forall(valid contains _)) return None
  val parts = bits.map{ case s =>
    if (bigset contains s) Right(bignum(big.indexOf(s)-1))
    else if (smallset contains s) Left(small.indexOf(s))
    else if (midset contains s) Left(20 + 10*mid.indexOf(s))
    else Left(100)
  }.foldLeft(List[Either[Int,BigInt]]()){ (xs,x) =>
    x match {
      case Left(i) => xs match {
        case Left(j) :: more =>
          if (i==100) {
            if (j>=10) return None else Left(i*j) :: more
          }
          else if (i > 10 && (j%100) != 0) return None
          else if ((j%10) != 0) return None
          else Left(i+j) :: more
        case _ => Left(i) :: xs
      }
      case Right(n) => xs match {
        case Right(m) :: more => Right(n*m) :: more
        case Left(j) :: more => Right(n*j) :: more
        case Nil => Right(n) :: Nil
      }
    }
  }.collect{ case Right(n) => n; case Left(i) => BigInt(i) }
  Some(parts.foldLeft(BigInt(0)){ (acc,x) =>
    if (acc > x) return None else acc+x
  })
}
Run Code Online (Sandbox Code Playgroud)

现在你可以:

scala> "five million eight hundred and one thousand and sixty-two"
res0: String = five million eight hundred and one thousand and sixty-two

scala> res0 match { case Longhand(n) => n }
res1: BigInt = 5801062

scala> Longhand.unapply("one and hundred billion five seven million")
res2: Option[BigInt] = None
Run Code Online (Sandbox Code Playgroud)

(在某些情况下,它会接受实际上没有正确格式化的内容,但拒绝格式错误的数字非常好.)