将阿拉伯数字转换为中国金融数字

如何解决将阿拉伯数字转换为中国金融数字

我正在尝试在函数式编程中创建一个函数,该函数将接收正常的Int值并将其转换为财务中文数字,并返回一个String,例如:301 =三百零一。首先,我有两张地图,一张地图的数字从0到9,另一张地图的指数从10到1000000。

val digits: Map[Int,String] = Map(0 -> "〇",1 -> "壹",2 -> "貳",3 -> "參",4 -> "肆",5 -> "伍",6 -> "陸",7 -> "柒",8 -> "捌",9 -> "玖");

val exponent: Map[Int,String] = Map(1 -> "",10 -> "拾",100 -> "佰",1000 -> "仟",10000 -> "萬",100000 -> "億",1000000 -> "兆");

对于不认识的人,这里对中文数字的工作原理进行一些解释。如果您已经知道,请不要阅读本段内容。在中文数字中,当您要写一个大数字(例如5000)时,请写下5和1000符号(伍仟)以表示您要乘以5 *1000。如果您有539,则为5 100 + 3 10 +9。这是伍佰参拾玖。最后,如果乘法之间的数字为0,则乘数无关紧要,在其他字符之间只写一个0。例如:501 = 5 100 +1。这是伍佰〇壹。最后一个校准示例:50103 = 5 10000 + 1 * 100 +3。这是伍万〇壹佰〇参。

所以我能做的是以下事情:

def format(unit: Int): String = {
val l = unit.toString.map(_.asDigit).toList
if(l.isEmpty) ""
else if(l.tail.isEmpty) digits(l.head)
else digits(l.head) + format(l.tail.mkString.toInt)
}

这将字符一一翻译。例如:

format(135) "壹參伍"

我不知道如何继续。

解决方法

如果我正确理解了您的问题,则可以执行以下操作:

def toChineseFinancial(number: Int): String = {
  val digits = number.toString.iterator.map(_.asDigit).toList
  val length = digits.length
  val exponents = List.tabulate(length)(n => math.pow(10,n).toInt)
  
  val (sb,_) =
    digits
      .iterator
      .zip(exponents.reverseIterator)
      .foldLeft(new collection.mutable.StringBuilder(length * 2) -> false) {
        case ((sb,flag),(digit,exp)) =>
          if (digit == 0) sb -> true
          else if (flag) sb.append("〇").append(digitsMap(digit)).append(exponentsMap(exp)) -> false
          else sb.append(digitsMap(digit)).append(exponentsMap(exp)) -> false
      }
  
  sb.result()
}

您可以看到它正在运行here


注意:我使用mutable.StringBuilder是因为构建字符串有点昂贵,但是如果您想避免任何类型的可变性,则可以轻松地将其替换为普通的字符串

,

我将使用简单的exponents来扩展case class地图的值,以涵盖:

  • 数量级1、10、10 ^ 2,...,10 ^ 12
  • “万”(10 ^ 4),“亿”(10 ^ 8)和“兆”(10 ^ 12)的10、100和1000'

如下所示:

case class CNU(unit: String,factor: Int)

val exponents: Map[Long,CNU] = Map(
  1L -> CNU("",1),10L -> CNU("拾",100L -> CNU("佰",1000L -> CNU("仟",10000L ->CNU("萬",100000L -> CNU("萬",10),1000000L -> CNU("萬",100),10000000L -> CNU("萬",1000),100000000L -> CNU("億",1000000000L -> CNU("億",10000000000L -> CNU("億",100000000000L -> CNU("億",1000000000000L -> CNU("兆",10000000000000L -> CNU("兆",100000000000000L -> CNU("兆",1000000000000000L -> CNU("兆",1000)
)

创建方法:

val digits: Map[Int,String] = Map(
  0 -> "〇",1 -> "壹",2 -> "貳",3 -> "參",4 -> "肆",5 -> "伍",6 -> "陸",7 -> "柒",8 -> "捌",9 -> "玖"
)

def toChineseNumber(num: Long): String = {
  val s = num.toString
  val ds = s.map(_.asDigit).zip(s.length-1 to 0 by -1)

  ds.foldRight(List.empty[String],0){ case ((d,i),(accList,dPrev)) =>
      val cnu = exponents(math.pow(10,i).toLong)

      val digit =
        if (d == 0) {
          if (dPrev != 0 || num == 0) digits(d) else ""
        }
        else
          digits(d)

      val unit =
        if (d == 0)
          "" 
        else {
          if (cnu.factor == 1) cnu.unit else exponents(cnu.factor).unit
        }

      ((digit + unit) :: accList,d)
    }.
    _1.mkString
}

请注意,方法foldRight用于从右向左遍历和处理输入数字,而元组累加器中的dPrev用于在迭代中携带数字以处理重复的0。

测试:

toChineseNumber(50)
// res1: String = 伍拾

toChineseNumber(30001)
// res2: String = 參萬〇壹

toChineseNumber(1023405)
// res3: String = 壹佰〇貳萬參仟肆佰〇伍

toChineseNumber(2233007788L)
// res4: String = 貳拾貳億參仟參佰〇柒仟柒佰捌拾捌

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?