向开始学习语言的的同学们推荐下,如果你想学习语言的某个特性,比方说数据库编程,或者网络编程,最好找一个实用的例子,然后不懂的去翻书,去查资料,这样目的性就很强了,个人感觉比对着语法书敲上面的例子效率要搞很多。
废话不多写了,说说我这个人民币大写转换的具体实现吧。
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+"整";
}
个人感觉我写的代码要少点,但具体谁的算法优劣,这个我还没有算他们两的时间和空间复杂度,感觉都差不多!