2013-03-04 6 views
0

Я пытаюсь написать программу, которая переведет число в его эквивалент строки. IE 987 654 321 = девятьсот восемьдесят семь миллионов шестьсот пятьдесят четыре тысячи триста двадцать один. Я прочитал в значение из консоли и я хочу итерацию через время цикла от г = 0 до string.lengthИтерация через цикл while в scala

пример

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

мой код ниже

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; 
      } 
     } 
     } 
    } 
+2

На ваш вопрос? – Noah

+3

Этот вопрос лучше подходит для CodeReview. –

+0

Извините, пытался подумать прошлой ночью, если бы я действительно опубликовал вопрос в этом вопросе или нет. Моя проблема заключается в том, что я запускаю это, чтобы ошибки в цикле while указывали, что найденный блок ожидает строку. Это не имело смысла для меня, вероятно, потому, что я думал, как java-программист, и (i) является int, а characters.length должен возвращать int по крайней мере то, что ожидал. что im пытается понять, как установить значение, скажем, i = 0 и цикл до конца массива. И у меня был тип-o в первом примере 1 строк должны были читать символы val = s.toCharArray; – Jeremy

ответ

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) 
} 

, который обрабатывает произвольные -строчные строки. У этого есть все, и кухня погружается в него (больше подходит для кодового гольфа, чем для целей обучения), но, возможно, вы можете взять некоторые указатели от него. В частности, вам следует попытаться использовать списки (массивы, векторы, что-то), чтобы избежать повторения себя снова и снова и снова и ...

Не задумываясь, какой самый большой беззнаковый длинный длинный (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 

Edit: ждать, что если вы хотите, чтобы решить обратную задачу? Просто вставьте это после того, как применяется и перед закрывающей скобкой:

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 
    }) 
} 

Теперь вы можете:

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 

(Есть несколько случаев, когда он будет принимать то, что на самом деле не правильно отформатированный, но это довольно хорошо об отказе от неправильных чисел.)

+0

Ах ах, удивительный. Почему у вас даже нет учетной записи в кодовом гольф? –

+0

Doh! Из учений вы это делаете. Мое черт возьми, у вас так много аккаунтов, что по вашему профилю ^^ по умолчанию указана только несколько штук. –

+0

Stream.continually ("over") уменьшить (_ + "и" + _) – pedrofurla

Смежные вопросы