我正在尝试编写一个将数字转换为等效字符串的程序。 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
}
我的代码在
之下 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;
}
}
}
}
答案 0 :(得分: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(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
编辑:等等,如果你想解决反问题怎么办?只需在apply之后和右括号之前插入:
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
(在某些情况下,它会接受实际上没有正确格式化的内容,但拒绝格式错误的数字非常好。)