发表于: 2017-07-26 02:45:55

2 959


问题:在解决两个零连在一起这个棘手的问题时候,有了下面的这个问题程序:

class Problem_1 

{

public static void main(String[] args) 

{

/*问题描述:

在获取一个String类型数据的最后一位时,使用了如下的两个方法。两个方法都能实现功能。但是能告诉我为什么输出结果是这样的?

*/

String s1 = "举杯对月饮尽晚风";

String s2 = s1.substring(s1.length()-1,s1.length());  //获取s1的最后一位字符

System.out.println("s2 = "+s2);

if (s2 == "风")

 {

   System.out.println("s2没问题!");

 }

else 

 {

   System.out.println("s2有问题!");

  }

int len = s1.length();

char c1 = s1.charAt(len-1);  //功能同s1

System.out.println("c1 = "+c1);

if (c1 == '风')

 {

   System.out.println("c1没问题!");

 }

else 

 {

   System.out.println("c1有问题!");

  }

}

}

上述程序的结果在日报结尾。

一 今天做的事情:

今天只做了一件事情:完成了将一个最高位最大为千位的浮点数转换成人民币读法的程序。在书上给了程序,但是有很多缺点,最大的缺点是对于零的处理。我参照了所给的程序,进一步完善了程序。

书上要求:

光盘中代码:

import java.util.Arrays;

/**

 * Description:

 * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a>

 * <br/>Copyright (C), 2001-2016, Yeeku.H.Lee

 * <br/>This program is protected by copyright laws.

 * <br/>Program Name:

 * <br/>Date:

 * @author Yeeku.H.Lee kongyeeku@163.com

 * @version 1.0

 */

public class Num2Rmb

{

private String[] hanArr = {"零" , "壹" , "贰" , "叁" , "肆" ,

"伍" , "陆" , "柒" , "捌" , "玖"};

private String[] unitArr = {"十" , "百" , "千"};

/**

* 把一个浮点数分解成整数部分和小数部分字符串

* @param num 需要被分解的浮点数

* @return 分解出来的整数部分和小数部分。第一个数组元素是整数部分,第二个数组元素是小数部分。

*/

private String[] divide(double num)

{

// 将一个浮点数强制类型转换为long,即得到它的整数部分

long zheng = (long)num;

// 浮点数减去整数部分,得到小数部分,小数部分乘以100后再取整得到2位小数

long xiao = Math.round((num - zheng) * 100);

// 下面用了2种方法把整数转换为字符串

return new String[]{zheng + "", String.valueOf(xiao)};

}

/**

* 把一个四位的数字字符串变成汉字字符串

* @param numStr 需要被转换的四位的数字字符串

* @return 四位的数字字符串被转换成的汉字字符串。

*/

private String toHanStr(String numStr)

{

String result = "";

int numLen = numStr.length();

// 依次遍历数字字符串的每一位数字

for (int i = 0 ; i < numLen ; i++ )

{

// 把char型数字转换成的int型数字,因为它们的ASCII码值恰好相差48

// 因此把char型数字减去48得到int型数字,例如'4'被转换成4。

int num = numStr.charAt(i) - 48;

// 如果不是最后一位数字,而且数字不是零,则需要添加单位(千、百、十)

if ( i != numLen - 1 && num != 0)

{

result += hanArr[num] + unitArr[numLen - 2 - i];

}

// 否则不要添加单位

else

{

result += hanArr[num];

}

}

return result;

}

    public static void main(String[] args)

    {

Num2Rmb nr = new Num2Rmb();

// 测试把一个浮点数分解成整数部分和小数部分

System.out.println(Arrays.toString(nr.divide(236711125.123)));

// 测试把一个四位的数字字符串变成汉字字符串

System.out.println(nr.toHanStr("609"));

    }

}

可以看出作者把最难的一部分留给了读者,用心良苦。

我的代码:

class EXP103

{

public static void main(String[] args)

{

/*

需求:

将一个浮点数(小数后最多两位数)转换成人民币读法字符串。

算法:

1 应使用查表法。

2 小数部分的处理:两位小数乘100得整数的两位数,若为一位数说明角为零,不打印;若为两位,若能乘除10说明分位为零,也不打印;若数为零,则小数部分不需要打印;除去上述三种情况,分别求出角位和分位的数,通过查表法来表示。若无小数,则打印“整”。

3 整数部分的处理:较为复杂。

 a 从非零位开始打印;

 b 若最低位为零,不打印;

 c 若有连续或两个以上的零时,只打印一个零;

步骤:

1 定义一个方法,把实现功能的程序封装在方法里;

2 定义两个数组,一个用于存放0-9的人民币写法,一个用于存放千"百十角分整"单位的人民币读法;

3 将浮点数分为整数和小数部分:整数部分直接用强制转换得到,小数部分用浮点数减去整数部分得到。

4 定义一个方法,用于封装实现小数部分的程序;

5 定义一个方法,用于封装实现整数部分的程序;

6 实在编不下去了,功能一点一点实现,代码改了又改,最终实现了功能。

*/

EXP103 impnum = new EXP103(); 

System.out.println("2000.13的人民币读法为: "+impnum.toHanStr(2000.13));//调用总方法将浮点数转换为大写数

System.out.println("200的人民币读法为:    "+impnum.toHanStr(200));//写了多个输出语句,测试正确性

System.out.println("2008.9的人民币读法为: "+impnum.toHanStr(2008.9));

System.out.println("2010的人民币读法为:   "+impnum.toHanStr(2010));

System.out.println("2500的人民币读法为:   "+impnum.toHanStr(2500));

System.out.println("60.12的人民币读法为:  "+impnum.toHanStr(60.12));

System.out.println("102.1的人民币读法为:  "+impnum.toHanStr(102.1));

System.out.println("1314.09的人民币读法为:"+impnum.toHanStr(1314.09));

}

private String[] cap = {"零" , "壹" , "贰" , "叁" , "肆" ,"伍" , "陆" , "柒" , "捌" , "玖"};

//存放0-9大写读法

private String[] unit = {"仟","百","十","角","分","整"};  //存放单位

private String toHanStr(double num) //总方法,在此方法中分离整数和小数,并调用将整数转换成大写的方法toZhengStr转换出大写整数,调用将小数转换成大写的方法toXiaoStr转换出大写小数,结果整合输出。

{

String result = "";

long zheng = (long)num; //存放整数

long xiao = Math.round((num - zheng)*100); //存放小数

result = toZhengStr(zheng) + toXiaoStr(xiao); //转换的整数和小数整合

return result; //返回整合

}

private String toZhengStr(long zheng) //将整数转换成大写的方法

{

String result = ""; //用于存放每步的结果

int zero = 0; 

/*

变量zero用于统计0出现的次数。

在想如果有两个零连在一起这个问题的时候,首先考虑的算法是定义一个变量作为计数器用于统计整数在转换时零出现的次数。于是就有了问题,花了大约一半的时间来解决这个问题。现在采用的方法最为方便,不用字符串或者字符来比较,就不会出现杂七杂八的问题。

*/ 

String zhengStr = String.valueOf(zheng); //求整数的长度

int zhengLen = zhengStr.length(); //获取整数的位数

long tho = zheng/1000; //tho存储千位

long hun = (zheng-tho*1000)/100; //hun存储百位

long ten = (zheng-tho*1000-hun*100)/10; //ten存储十位

long sin = zheng-tho*1000-hun*100-ten*10; //sin存储个位

long[] zhengHe = {tho ,hun ,ten ,sin }; //这个数组用于存放各位数

for (int i = 4-zhengLen ;i<4 ;i++ ) 

//由于编程经验不足,这个表达式花了好久的时间,前后用了if和switch语句,写着写着就写成了for语句

{

if ((hun == 0 && ten == 0 && sin == 0) || (ten == 0 && sin == 0))

//判断整数部分是不是整千或者整百,这种情况最特殊

{

int temp = (int)zhengHe[i]; //表达式cap[(int)zhengHe[i]];是错误的,所以只好定义一个变量

if (temp == 0)

{

continue; //如果数字为零,终止本次循环,直接进入下次循环

}

else

{

result += cap[temp] + unit[i]; //非零的话转换数而且加单位

}

}

else if (zero != 1 && i != 3) 

//在整数不是整千或者整百的情况下考虑(接下来的四个if嵌套都是的),这个if接着考虑的是若没有零而且i没有循环到最后一位的情况

{

int temp = (int)zhengHe[i];

if (temp == 0)

{

zero++;  //若有零,zero则加1

result += cap[temp]; //因为是零,所以不加单位

}

else

{

result += cap[temp]+unit[i];  //非零,转换加单位

}

}

else if(zero  == 1 && i != 3) //这个if考虑已经有一个零了但是i还没有循环到最后一位

{

int temp = (int)zhengHe[i];

if (temp == 0)

{

continue; //如果又有一个零,则终止本次循环,直接进入下次循环

}

else

{

result += cap[temp] + unit[i]; //非零,转换加单位

}

}

else if (zero !=1 && i ==3) //这个if考虑没有零但是i已经循环到最后一位了

{

int temp = (int)zhengHe[i]; 

result += cap[temp]; //最后一位不加单位

}

else if(zero ==1 && i ==3) //这个if考虑有一个零而且已经循环到最后一位了

{

int temp = (int)zhengHe[i];

if (temp == 0) //最后一位若为零,则终止当前循环,也就终止了所有循环

{

continue;

}

else

{

result += cap[temp]; //最后一位非零,不加单位地转换

}

}

}

return result; //返回最终转换的整数结果

}

private String toXiaoStr(long xiao) //将小数转换成大写的方法

{

String result = ""; //用于存放每步的结果

int jiao = (int)xiao/10; //求得角位数字

int fen = (int)xiao-jiao*10;  //求得分位数字

if (jiao == 0 && fen == 0) //若角分位同时为零,则打印“整”

{

result += unit[5];

}

else if (jiao == 0)  //若角位为零,只打印分位

{

result += cap[fen] + unit[4];

}

else if (fen == 0) //若分位为零,只打印角位

{

result += cap[jiao] + unit[3];

}

else if (jiao != 0 && fen != 0) //若角分位都不为零,都打印

{

result += cap[jiao] + unit[3] + cap[fen] + unit[4];

}

return result; //将result作为返回值返回

}

}

代码结束符

在EditPlus中代码格式好好的,上传网页就没格式了,也懒得改了一百多行的代码。

功能是实现了,但是我总觉得有更好的算法。

我的程序结果:

完成。耗费了很多时间,但是觉得值,最起码比安装软件解决软件安装问题值。

二 明天完成的事情:

按照这进度,明天能完成五子棋就很不错了。

完成了五子棋之后要是还有空的话可以考虑这个程序怎么实现千位以上的读法,应该不会很难,这个程序最难的已经解决了。


问题程序的结果:

求解答。



返回列表 返回列表
评论

    分享到