JavaScript实现中文数字与阿拉伯数字的相互转换
最编程
2024-01-15 19:07:40
...
阿拉伯数字转中文数字
中文数字的特点:
- 每个计数数字都跟着一个权位,权位有:十、百、千、万、亿。
- 以“万”为小节,对应一个节权位,万以下没有节权位。
- 每个小节内部以“十百千”为权位独立计数。
- “十百千”不能连续出现,而“万”和“亿”作为节权位时可以和其他权位连用,如:“二十亿”。
中文数字对“零”的使用要满足以下三条规则:
- 以10000为小节,小节的结尾即使是0,也不使用零。
- 小节内两个非0数字之间要使用“零”。
- 当小节的“千”位是0时(即:1~999),只要不是首小节,都要补“零”。
算法设计的一些说明:
- 对“零”的第三个规则,把检测放在循环的最前面并默认为false,可以自然的丢弃最高小节的加零判断。
- 单个数字转换用数组实现,var chnNumChar = ["零","一","二","三","四","五","六","七","八","九"];
- 节权位同样用数组实现,var chnUnitSection = ["","万","亿","万亿","亿亿"];
- 节内权位同样用数组实现,var chnUnitChar = ["","十","百","千"];
节内转换算法:
function SectionToChinese(section){ var strIns = '', chnStr = ''; var unitPos = 0; var zero = true; while(section > 0){ var v = section % 10; if(v === 0){ if(!zero){ zero = true; chnStr = chnNumChar[v] + chnStr; } }else{ zero = false; strIns = chnNumChar[v]; strIns += chnUnitChar[unitPos]; chnStr = strIns + chnStr; } unitPos++; section = Math.floor(section / 10); } return chnStr; }
转换算法主函数:
function NumberToChinese(num){ var unitPos = 0; var strIns = '', chnStr = ''; var needZero = false; if(num === 0){ return chnNumChar[0]; } while(num > 0){ var section = num % 10000; if(needZero){ chnStr = chnNumChar[0] + chnStr; } strIns = SectionToChinese(section); strIns += (section !== 0) ? chnUnitSection[unitPos] : chnUnitSection[0]; chnStr = strIns + chnStr; needZero = (section < 1000) && (section > 0); num = Math.floor(num / 10000); unitPos++; } return chnStr; }
中文数字转阿拉伯数字
设计思想:
- 将中文数学转换成阿拉伯数字。
- 将中文权位转换成10的位数。
- 对每个权位依次转换成位数并求和。
- 零直接忽略即可。
中文数字转换成阿拉伯数字用如下对象实现:
var chnNumChar = { 零:0, 一:1, 二:2, 三:3, 四:4, 五:5, 六:6, 七:7, 八:8, 九:9 };
中文权位转换成10的位数及节权标志用如下对象实现:
var chnNameValue = { 十:{value:10, secUnit:false}, 百:{value:100, secUnit:false}, 千:{value:1000, secUnit:false}, 万:{value:10000, secUnit:true}, 亿:{value:100000000, secUnit:true} }
转换算法如下:
function ChineseToNumber(chnStr){ var rtn = 0; var section = 0; var number = 0; var secUnit = false; var str = chnStr.split(''); for(var i = 0; i < str.length; i++){ var num = chnNumChar[str[i]]; if(typeof num !== 'undefined'){ number = num; if(i === str.length - 1){ section += number; } }else{ var unit = chnNameValue[str[i]].value; secUnit = chnNameValue[str[i]].secUnit; if(secUnit){ section = (section + number) * unit; rtn += section; section = 0; }else{ section += (number * unit); } number = 0; } } return rtn + section; }
推荐阅读
-
一种结构设计模式,允许在对象中动态添加新行为。它通过创建一个封装器来实现这一目的,即把对象放入一个装饰器类中,然后把这个装饰器类放入另一个装饰器类中,以此类推,形成一个封装器链。这样,我们就可以在不改变原始对象的情况下动态添加新行为或修改原始行为。 在 Java 中,实现装饰器设计模式的步骤如下: 定义一个接口或抽象类作为被装饰对象的基类。 公共接口 Component { void operation; } } 在本例中,我们定义了一个名为 Component 的接口,该接口包含一个名为 operation 的抽象方法,该方法定义了被装饰对象的基本行为。 定义一个实现基类方法的具体装饰对象。 公共类 ConcreteComponent 实现 Component { public class ConcreteComponent implements Component { @Override public void operation { System.out.println("ConcreteComponent is doing something...") ; } } 定义一个抽象装饰器类,该类继承于基类,并将装饰对象作为一个属性。 公共抽象类装饰器实现组件 { protected Component 组件 public Decorator(Component component) { this.component = component; } } @Override public void operation { component.operation; } } } 在这个示例中,我们定义了一个名为 Decorator 的抽象类,它继承了 Component 接口,并将被装饰对象作为一个属性。在操作方法中,我们调用了被装饰对象上的同名方法。 定义一个具体的装饰器类,继承自抽象装饰器类并实现增强逻辑。 公共类 ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component 组件) { super(component); } } public void operation { super.operation System.out.println("ConcreteDecoratorA 正在添加新行为......") ; } } 在本例中,我们定义了一个名为 ConcreteDecoratorA 的具体装饰器类,它继承自装饰器抽象类,并实现了操作方法的增强逻辑。在操作方法中,我们首先调用被装饰对象上的同名方法,然后添加新行为。 使用装饰器增强被装饰对象。 公共类 Main { public static void main(String args) { Component 组件 = new ConcreteComponent; component = new ConcreteDecoratorA(component); 组件操作 } } 在这个示例中,我们首先创建了一个被装饰对象 ConcreteComponent,然后通过 ConcreteDecoratorA 类创建了一个装饰器,并将被装饰对象作为参数传递。最后,调用装饰器的操作方法,实现对被装饰对象的增强。 使用场景 在 Java 中,装饰器模式被广泛使用,尤其是在 I/O 中。Java 中的 I/O 库使用装饰器模式实现了不同数据流之间的转换和增强。 让我们打开文件 a.txt,从中读取数据。InputStream 是一个抽象类,FileInputStream 是专门用于读取文件流的子类。BufferedInputStream 是一个支持缓存的数据读取类,可以提高数据读取的效率,具体代码如下: @Test public void testIO throws Exception { InputStream inputStream = new FileInputStream("C:/bbb/a.txt"); // 实现包装 inputStream = new BufferedInputStream(inputStream); byte bytes = new byte[1024]; int len; while((len = inputStream.read(bytes)) != -1){ System.out.println(new String(bytes, 0, len)); } } } } 其中 BufferedInputStream 对读取数据进行了增强。 这样看来,装饰器设计模式和代理模式似乎有点相似,接下来让我们讨论一下它们之间的区别。 第三,与代理模式的区别: 代理模式的目的是控制对对象的访问,它在对象外部提供一个代理对象来控制对原对象的访问。代理对象和原始对象通常实现相同的接口或继承相同的类,以确保两者可以相互替换。 装饰器模式的目的是动态增强对象的功能,而这是通过对象内部的包装器来实现的。在装饰器模式中,装饰器类和被装饰对象通常实现相同的接口或继承自相同的类,以确保两者可以相互替代。装饰器模式也被称为封装器模式。 在代理模式中,代理类附加了与原类无关的功能。
-
Java 将实现对象与 Map 的相互转换--使用 BeanMap
-
利用Iconfont矢量图标与Iconmoon svg转换结合JavaScript,打造社交分享功能的轻松实现方案
-
如何迅速在JavaScript中实现简繁体中文间的切换:实用技巧与网站支持简繁体转换的秘密武器
-
在Java中轻松实现图片与二进制数据之间的相互转换
-
JavaScript实现中文数字与阿拉伯数字的相互转换
-
JavaScript 阿拉伯数字与中文数字互相转换
-
在Qt中轻松实现16进制与10进制的相互转换
-
C#实现十六进制颜色与Color对象的相互转换