向開始學習語言的的同學們推薦下,如果你想學習語言的某個特性,比方說數據庫編程,或者網絡編程,最好找一個實用的例子,然後不懂的去翻書,去查資料,這樣目的性就很強了,個人感覺比對着語法書敲上面的例子效率要搞很多。
廢話不多寫了,說說我這個人民幣大寫轉換的具體實現吧。
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+"整";
}
個人感覺我寫的代碼要少點,但具體誰的算法優劣,這個我還沒有算他們兩的時間和空間複雜度,感覺都差不多!