向开始学习语言的的同学们推荐下,如果你想学习语言的某个特性,比方说数据库编程,或者网络编程,最好找一个实用的例子,然后不懂的去翻书,去查资料,这样目的性就很强了,个人感觉比对着语法书敲上面的例子效率要搞很多。

废话不多写了,说说我这个人民币大写转换的具体实现吧。

1.写了个简单的界面,这个没什么要讲的,直接贴代码了,本片博客主要讲的是算法的实现。

Panel panel1=new Panel(); Panel panel2=new Panel(); Panel panel3=new Panel(); Label label1=new Label("Primitive money"); // label1.setFont(new Font("黑体",1,30)); TextField text1=new TextField(20); Label label2=new Label("Big money"); //label2.setFont(new Font("黑体",1,30)); TextField text2=new TextField(20); public RmbConvert() { initComponent();//面板初始化 } private void initComponent() { setTitle("人民币大写转换"); setSize(345,216); setLayout(new GridLayout(3,1));//设置为Grid布局 panel1.add(label1); panel1.add(text1); panel2.add(label2); panel2.add(text2); Button bt=new Button("Confirm"); panel3.add(bt); add(panel1); add(panel2); add(panel3); //添加事件监听器 bt.addActionListener(this); text1.addActionListener(this); addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } } ); }界面效果如下:

2.大写转换算法实现

  • 定义要用到的数组

String[] digit={"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"}; String[] segment={"圆","万","亿","万亿"}; String[] unit={"仟","佰","拾",""}; String[] cent={"角","分"};

  • 获取输入字符的整数部分的转换

//保留两位有效数字 value=round(value,2);//round为自定义函数,非java.Math中的函数,value为界面当中输入的阿拉伯数字,为double类型 //大金额的浮点数会被自动表示成科学计数法,转换不方便,所以先将其变成整数 String valStr=String.valueOf((long)(value*100)); //取整数部分 String preStr=valStr.substring(0,valStr.length()-2); //取小数部分 String sufStr=valStr.substring(valStr.length()-2); String prffixPart="";//存放转换整数部分的大写字符 String suffixPart="";//存放转换小数部分的大写字符 for(int i=0;i<preStr.length();i++) { int index=Integer.parseInt(preStr.substring(i,i+1)); int temp=4-(preStr.length()-i)%4; if(temp==4) { temp=0; if(i!=0&&segmentEnd(i,preStr))//判断输入进位,该位置所在段的四位全为零,则该段不需要加 prffixPart+=segment[(preStr.length()-i-1)/4+1]; } if(index!=0) prffixPart+=digit[index]+unit[temp]; } prffixPart+="圆";

在这详细说一下我的算法实现

这里我是自己想的一个算法,没有用书上的那个先将整数部分分成每四个数一段然后来处理,我是直接通过整个整数部分的长度preStr.length()首先就确定了要在什 么位置加上亿,万,圆等segment。

int temp=4-(preStr.length()-i)%4;

这句的目地是就是得到每四位中具体那一位后面加什么单位,temp取值是1,2,3,4分别对应佰,拾,“”,仟,但是4已经造成数组越界,随意我下面写了个判断,让其在4时将0赋值给temp;

if(i!=0&&segmentEnd(i,preStr))//判断输入进位,该位置前四位全不为零
prffixPart+=segment[(preStr.length()-i-1)/4+1];

这两句很关键,主要就是判断什么时候该加“万”了,什么时候该加“圆”了,因为只有当temp=4,下面一句就是要加上“几”“仟”了,正好在这之前加上“万”“圆”等

  • 数取输入小数部分的大写转换

//处理小数部分 for(int i=0;i<sufStr.length();i++) { int index=Integer.parseInt(sufStr.substring(i,i+1)); if(index!=0) suffixPart+=digit[index]+cent[i]; } return prffixPart+suffixPart+"整";

  • 重写的round函数

public double round(double value,int scale) { return Math.round(value*(Math.pow(10.0,scale)))/(Math.pow(10.0,scale)); }

  • 自定义的segmentEnd函数

//判断当四位全是零时就不必再加上segment //当需要加入segment返回ture,否则返回false private boolean segmentEnd(int i,String preStr) { for(int j=i-1;j>i-5&&j>=0;j--) { int index=Integer.parseInt(preStr.substring(j,j+1)); if(index==0) continue; else return true; } return false; }


先贴上我的完整代码

import java.awt.*; import java.awt.event.*; import java.lang.Math; import java.lang.Integer.*; public class RmbConvert extends Frame implements ActionListener { Panel panel1=new Panel(); Panel panel2=new Panel(); Panel panel3=new Panel(); Label label1=new Label("Primitive money"); // label1.setFont(new Font("黑体",1,30)); TextField text1=new TextField(20); Label label2=new Label("Big money"); //label2.setFont(new Font("黑体",1,30)); TextField text2=new TextField(20); public RmbConvert() { initComponent();//面板初始化 } private void initComponent() { setTitle("人民币大写转换"); setSize(345,216); setLayout(new GridLayout(3,1));//设置为Grid布局 panel1.add(label1); panel1.add(text1); panel2.add(label2); panel2.add(text2); Button bt=new Button("Confirm"); panel3.add(bt); add(panel1); add(panel2); add(panel3); //添加事件监听器 bt.addActionListener(this); text1.addActionListener(this); addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } } ); } public void actionPerformed(ActionEvent e) { UppercaseRMB cc=new UppercaseRMB(); text2.setText(cc.changeToUppercase(Double.parseDouble(text1.getText()))); } public static void main(String[] args) { new RmbConvert().setVisible(true); } } class UppercaseRMB { String[] digit={"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"}; String[] segment={"圆","万","亿","万亿"}; String[] unit={"仟","佰","拾",""}; String[] cent={"角","分"}; public String changeToUppercase(double value) { //保留两位有效数字 value=round(value,2); //大金额的浮点数会被自动表示成科学计数法,转换不方便,所以先将其变成整数 String valStr=String.valueOf((long)(value*100)); //取整数部分 String preStr=valStr.substring(0,valStr.length()-2); //取小数部分 String sufStr=valStr.substring(valStr.length()-2); String prffixPart="";//存放转换整数部分的大写字符 String suffixPart="";//存放转换小数部分的大写字符 for(int i=0;i<preStr.length();i++) { int index=Integer.parseInt(preStr.substring(i,i+1)); int temp=4-(preStr.length()-i)%4; if(temp==4) { temp=0; if(i!=0&&segmentEnd(i,preStr))//判断输入进位,该位置前四位全不为零 prffixPart+=segment[(preStr.length()-i-1)/4+1]; } if(index!=0) prffixPart+=digit[index]+unit[temp]; } prffixPart+="圆"; //处理小数部分 for(int i=0;i<sufStr.length();i++) { int index=Integer.parseInt(sufStr.substring(i,i+1)); if(index!=0) suffixPart+=digit[index]+cent[i]; } return prffixPart+suffixPart+"整"; } //判断当四位全是零时就不必再加上segment //当需要加入segment返回ture,否则返回false private boolean segmentEnd(int i,String preStr) { for(int j=i-1;j>i-5&&j>=0;j--) { int index=Integer.parseInt(preStr.substring(j,j+1)); if(index==0) continue; else return true; } return false; } //按照一定精度对小数进行四舍五入的函数 public double round(double value,int scale) { return Math.round(value*(Math.pow(10.0,scale)))/(Math.pow(10.0,scale)); } }
下面的这个是书上实现大写转换的代码,他是通过现将整数部分每四位一段,然后一段一段的转换

public String changeToUppercase(double value) { //保留两位有效数字 value=round(value,2); //大金额的浮点数会被自动表示成科学计数法,转换不方便,所以先将其变成整数 String valStr=String.valueOf((long)(value*100)); //取整数部分 String preStr=valStr.substring(0,valStr.length()-2); //取小数部分 String sufStr=valStr.substring(valStr.length()-2); //退出循环的标记 boolean isEnd=false; //用于循环遍历段名数组的下标变量 int vunitindex=""; String prffixPart="";//存放转换整数部分的大写字符 String suffixPart="";//存放转换小数部分的大写字符 while(true) { //得到段的起始位置 int begin=preStr.length()-4; //防止段起始下标越界 if(begin<0) begin=0; //取得段 String temps=preStr.substring(begin); //处理段中每个数值的临时字符串变量 String result=""; //循环处理段中的每个数值 for(int i=0;i<temps.length();i++) { int index=Interger.parseInt(temps.substring(i,i+1)); if(index!=0) result+=digit[index]+unit[i]; } //加上段名称 result+=segment[vunitindex++]; //形成大写表示的整数结果 prefixPart=result+prefixPart; //得到需要继续处理的金额部分 preStr=preStr.substring(0,begin); //判断是否结束 if(isEnd||preStr.length()==0) break; //如果段中数值位数小于4,补零与前构成四位(这种情况会发生在金额的首几位) String space=""; for(int i=0;i<4-preStr.length();i++) { space+="0" isEnd=true; } preStr=spaces+preStr; //处理小数部分 for(int i=0;i<sufStr.length();i++) { int index=Integer.parseInt(sufStr.substring(i,i+1)); if(index!=0) suffixPart+=digit[index]+cent[i]; } return prffixPart+suffixPart+"整"; }
个人感觉我写的代码要少点,但具体谁的算法优劣,这个我还没有算他们两的时间和空间复杂度,感觉都差不多!