Java学习笔记---字符串操作(人民币大写转换的实现)

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

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

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+"整"; }
个人感觉我写的代码要少点,但具体谁的算法优劣,这个我还没有算他们两的时间和空间复杂度,感觉都差不多!






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
//ChangeRMB.java /** * * programmed by HuangHeliang * 2009.04.15 10:20:51 * */ //package com.avtech.hhl; import java.io.*; public final class ChangeRMB { //每个数字对应的大写 private static final String[] num = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖", }; //从低到高排列的单位 private static final String[] bit = { "圆", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿" }; //金额里面的角和分 private static final String[] jf={ "角","分" }; /** * 处理金额的整数部分,返回"...圆整" * @param integer * @return String * @throws Exception */ public static String praseUpcaseRMB(String integer)throws Exception{ StringBuilder sbdr=new StringBuilder(""); int j=integer.length(); if(j>bit.length){ throw new Exception("\n只能处理亿万亿以内的数据(含亿万亿)!"); } char[] rmb=integer.toCharArray(); for (int i = 0; i 壹佰亿陆仟伍佰万肆仟伍佰捌拾叁圆零伍分 */ if(bit[bitLocate].equals("仟")){ String s=sbdr.toString(); if(!s.endsWith(bit[bitLocate+1]) && s.length()>0){ if (s.endsWith(num[0])) { sbdr.deleteCharAt(sbdr.length() - 1); } sbdr.append(bit[bitLocate+1]); } } sbdr.append(num[numLocate]); sbdr.append(bit[bitLocate]); }//end for /* * 去掉结尾"零"后,补全 */ if(sbdr.toString().endsWith(num[0])){ sbdr.deleteCharAt(sbdr.length()-1); sbdr.append("圆整"); }else{ sbdr.append("整"); } return sbdr.toString(); } /** * 处理带小数的金额,整数部分交由上一个方法处理,小数部分自己处理 * @param integer * @param decimal * @return String * @throws Exception */ public static String praseUpcaseRMB(String integer, String decimal)throws Exception{ String ret=ChangeRMB.praseUpcaseRMB(integer); ret=ret.split("整")[0]; //处理整数部分 StringBuilder sbdr=new StringBuilder(""); sbdr.append(ret); char[] rmbjf=decimal.toCharArray(); for(int i=0;i rmbDouble){ theInt-=1; } double theDecimal=rmbDouble-theInt; String integer=new Long((long)theInt).toString(); String decimal=""+Math.round(theDecimal*100); if(decimal.equals("0")){ result=ChangeRMB.praseUpcaseRMB(integer); }else{ result=ChangeRMB.praseUpcaseRMB(integer, decimal); } return result; } public static void main(String[] args) throws Exception{ System.out.print("输入小写人民币金额:"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String in = br.readLine(); String result=ChangeRMB.doChangeRMB(in); System.out.println("\n"+"------------转换结果------------"); System.out.println(result); double d=54628569856.68; String ret=ChangeRMB.doChangeRMB(d); System.out.println("\n"+"------------转换结果------------"); System.out.println(ret); } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值