黑马程序员技术交流社区
标题: 分享笔试题:金额转换 [打印本页]
作者: sanguodouble1 时间: 2014-5-27 01:44
标题: 分享笔试题:金额转换
本帖最后由 sanguodouble1 于 2014-5-29 22:36 编辑
需求:金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。
分析:对于小数位,由于现在最小面值是分,所以只取两位小数。
对于整数位,比较难解决的是多个零连续出现时的表示方法,当多个零连续出现时,一般在中文中只显示一个零,
比如1001,就是“壹仟零壹元”,但如果这个0是处于关键位是(万、亿位),那么这个零的单位就不能省了,比如100000,就是“壹拾万元整”。
然后根将这两部分合理相加
下面是我的代码,(做了好几小时,惭愧:o)
- public class ConvertCurrency {
- public static void main(String[] args) {
- //因为最小单位就是分,所以暂时设定最小只能输入两个小数,整数不限
- String str = "¥3540.01";
- parse(str);
- integrated();
- }
-
- public static void parse(String str) {
- //定义一个正则表达式,作用:去掉整数位最前面的0,把整数位(第一组)和小数位(第3组)区别开来
- Pattern p = Pattern.compile("¥{0,1}0*(\\d{1,})(\\.(\\d{1,2})){0,1}");
- Matcher m = p.matcher(str);
- if (p.matcher(str).matches()) {
- while (m.find()) {
- String intPart = m.group(1);
- // 转换整数部分
- transInt(intPart);
- String decimalPart = m.group(3);
- // 转换小数部分
- transDec(decimalPart);
- }
- } else {
- System.out.println("格式不对");
- return;
- }
- }
-
- //最后输出时,把整数部分和小数部分整合起来
- public static void integrated() {
- if (intSB.length() == 0) {
- if (decSB.length() == 0) {
- System.out.println("0元整");
- } else {
- System.out.println(decSB);
- }
- } else {
- if (decSB.length() == 0) {
- System.out.println(intSB + "整");
- } else {
- System.out.print(intSB);
- System.out.println(decSB);
- }
- }
-
- }
-
- //这个用来放整数部分
- static StringBuilder intSB = new StringBuilder();
- public static void transInt(String intPart) {
- long sum = Long.valueOf(intPart); //之所以用Long,是因为int只有4个字节,最多支持21亿,Long的话,2的63次方,世界首富看了都傻眼
- if (sum == 0) {
- return; //如果整数部分是0的话
- } else {
- intSB.insert(0, "元");
- }
-
- int pos = 0; //记录当前处于整个数字中的第几位
- boolean isZeroSequence = false; //出现连续0的标志
- while (sum != 0) {
- pos++; //当前位数
- int temp = (int)(sum % 10); //得到当前位是几
- if (temp == 0) {
- addUnit(pos, true); //先加上单位
- if (!isZeroSequence) { //如果不是连续的出现0
- if (pos != 1) { //如果不是个位的情况下,因为如果个位是0,可以直接跳过
- String str = getChin(temp);
- intSB.insert(0, str);
- }
- isZeroSequence = true; //因为已经出现了一次0,所以先标记上
- }
- sum = sum / 10; //去掉已经分析的一位
- } else {
- isZeroSequence = false; //既然这位不是0,那么把连续0的状态清除
- addUnit(pos, false); //加上单位
- String str = getChin(temp);
- intSB.insert(0, str);
- sum = sum / 10; //去掉已经分析的一位
- }
- }
-
- }
-
- public static void addUnit(int pos, boolean isZero) {
- String unit;
- if (!isZero || pos%4==1) { //如果当前为不是0,或者当前位是0,但这个0处于万、亿位置上
- if (pos <= 9) { //小于9位数的情况下
- unit = getUnit(pos);
- intSB.insert(0, unit);
- } else { //如果已经大于9位数
- int tempPos = pos - 8;
- while (tempPos > 8) {
- tempPos -= 8;
- }
- unit = getUnit(tempPos);
- intSB.insert(0, unit);
- }
- }
- }
-
- //这个用来放小数部分
- static StringBuilder decSB = new StringBuilder();
- public static void transDec(String decPart) {
- if (decPart == null) {
- // decSB.append("整"); //如果没有小数位,那就是整数
- return;
- }
- int i = Integer.parseInt(decPart);
- if (i == 0) {
- // decSB.append("整"); //如果没有小数位,那就是整数
- return;
- }
- if (decPart.length() == 1) { //如果只有一位小数的话
- decSB.append(getChin(i));
- decSB.append(getUnit(-1));
- } else if (decPart.length() == 2) { //如果有两位小数的话
- if (i<10) { //两位小数转化过来只有一位,那么肯定是角位必为0
- decSB.append(getChin(0));
- decSB.append(getChin(i));
- decSB.append(getUnit(-2));
- } else {
- int jiao = i/10;
- decSB.append(getChin(jiao));
- decSB.append(getUnit(-1));
- int fen = i%10;
- if (fen == 0) return;
- decSB.append(getChin(fen));
- decSB.append(getUnit(-2));
- }
- }
- }
-
-
-
- // 壹拾贰亿叁仟肆佰伍拾陆万柒仟捌佰玖拾元整零
- public static String getChin(int i) {
- switch (i) {
- case 0 : return "零";
- case 1 : return "壹";
- case 2 : return "贰";
- case 3 : return "叁";
- case 4 : return "肆";
- case 5 : return "伍";
- case 6 : return "陆";
- case 7 : return "柒";
- case 8 : return "捌";
- case 9 : return "玖";
- default :
- return "error1";
- }
- }
- // 计算不大于9位数的单位
- public static String getUnit(int i) {
- switch (i) {
- case -2 : return "分";
- case -1 : return "角";
- case 1 : return ""; //如果小于9位数,这个可以输出“元”,但这样一来,对大于9位数的操作就比较麻烦了,所以把“元这个单位放到62行上”
- case 2 : return "拾";
- case 3 : return "佰";
- case 4 : return "仟";
- case 5 : return "万";
- case 6 : return "拾";
- case 7 : return "佰";
- case 8 : return "仟";
- case 9 : return "亿";
- default :
- return "error2";
- }
- }
- }
复制代码
不足之处,请指正,如有好的想法,欢迎交流,共同进步
作者: 136616244 时间: 2014-5-27 01:54
需要这么复杂吗?反正我是懒得看:lol,代码太多,估计没几个人会看
作者: ★魔_➩τ咒 时间: 2014-5-27 06:42
这是第四步的笔试题?
作者: Queen123 时间: 2014-5-27 07:33
努力了,支持一下
作者: wuhyoung 时间: 2014-5-27 07:56
支持一下楼主
作者: 为了明天 时间: 2014-5-27 09:05
感觉好复杂
作者: Solomon 时间: 2014-5-27 09:09
楼主赞!!!!!!!!!!!
作者: GGdog 时间: 2014-5-27 11:52
你好,这是面试时候的笔试题还是被录取之后报道时候的笔试题目啊?
作者: 路漫漫_求索 时间: 2014-5-27 13:41
楼主的功力不错啊
作者: sanguodouble1 时间: 2014-5-27 13:49
什么也不是,你看过张孝祥老师的面试宝典吗?
那里有一个“算法与编程”,这个就是最后一题,我习惯是先自己做,再看老师答案,但那个答案我有点失望,因为不符合现实中真正的转换规律
- public class RenMingBi {
- /**
- * @param args add by zxx ,Nov 29, 2008
- */
- private static final char[] data = new char[]{
- '零','壹','贰','叁','肆','伍','陆','柒','捌','玖'
- };
- private static final char[] units = new char[]{
- '元','拾','佰','仟','万','拾','佰','仟','亿'
- };
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- System.out.println(
- convert(135689123));
- }
- public static String convert(int money)
- {
- StringBuffer sbf = new StringBuffer();
- int unit = 0;
- while(money!=0)
- {
- sbf.insert(0,units[unit++]);
- int number = money%10;
- sbf.insert(0, data[number]);
- money /= 10;
- }
- return sbf.toString();
- }
- }
复制代码 贴给你看一下,或许你有新的想法
作者: 27ZJQ 时间: 2014-5-27 13:57
还没学到,不懂。
作者: chang清 时间: 2014-6-10 13:00
我基入学测试也遇到这个题了,代码稍微比这个少一点,思想也不难理解(搞了差不多一个下午吧);分享了交流一下吧;
public class Test10 {
/*
* 10、 金额转换,阿拉伯数字转换成中国传统形式。 例如:101000001010 转换为 壹仟零壹拾亿零壹仟零壹拾圆整
*/
public static void main(String[] args) {
long value = 456789;//数值11111101000001010
System.out.println(trans(value));
}
public static String trans(long value){
if(String.valueOf(value).length()>17){//可以支持更大的位数只需要在unit数组中添加单位即可
return "超出计算范围,请重新输入(小于17位为有限范围)。";
}
char[] chinses = new char[] { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌','玖' };
//单位
char[] unit = new char[] {' ', ' ', '拾', '佰', '仟','万'};
// 接收到的数字转换成数字字符串
StringBuilder sBuilderVal = new StringBuilder(String.valueOf(value));
sBuilderVal = sBuilderVal.reverse();
//存放返回结果
StringBuilder reVal = new StringBuilder();
int count = 1 ;
//由于数值到亿的时候每次的单位变化就是在前一次单位加上亿的单位
int num = 4 ;
while(sBuilderVal!=null){
if(count>=4){
num++;
}
StringBuilder countVal = new StringBuilder();
StringBuilder tempVal = new StringBuilder();
if(sBuilderVal.length()<=num){
//如果串长度没有四位则取出所有字符
tempVal.append(sBuilderVal.substring(0, sBuilderVal.length()));
//表示已经取出所有字符,设置程序出口
sBuilderVal = null ;
}else{
//每次取出的位用于转换
tempVal.append(sBuilderVal.substring(0,num));
sBuilderVal = sBuilderVal.delete(0, num);
}
tempVal = tempVal.reverse();
int zeroCount = 0;
for(int i = 0 ; i<tempVal.length();i++){
int cVal = Integer.parseInt(String.valueOf(tempVal.charAt(i)));
//如果连续两个或两个以上的零则不添加到结果中
if(cVal==0 && zeroCount==0){
countVal.append(chinses[cVal]);
zeroCount++;
}else if(cVal!=0){
//如果取出的数字不是连续的零则存储到结果中
countVal.append(chinses[cVal]);
countVal.append(unit[tempVal.length()-i]);
}
}
//设置单位
if(!countVal.toString().endsWith("零")){
switch(count){
case 1 :
countVal.append("圆整");
break ;
case 2 :
countVal.append("万");
break;
case 3 :
countVal.append("亿");
break ;
case 4 :
countVal.append("兆");
break;
}
}
count++;
reVal.insert(0, countVal);
}
return reVal.toString() ;
}
}
作者: yinxjfly 时间: 2014-6-10 15:30
楼主正解!
作者: 蒙鹏飞 时间: 2014-6-10 16:12
完全不懂.....不知道43期深圳能不能过啊
作者: 钟翠翠 时间: 2014-7-29 13:20
不觉明历,表示完全看不懂啊!!
作者: 嘿~~ 时间: 2014-10-17 14:58
我的笔试题也是这个,最后一道提,可是我没看正则表达式啊,,郁闷死了
作者: winkyqin 时间: 2014-10-19 14:00
楼主赞!
作者: 齐宁宁 时间: 2014-10-20 09:04
大神很厉害啊!赞一个
作者: 齐宁宁 时间: 2014-10-20 10:08
谢谢你的分享,很厉害
作者: jiangwenjun 时间: 2015-1-25 02:15
这也太复杂了吧!用制表法那种方式,可以缩短很多代码!不过按照你的思路没有错! 不过用制表法的思维快多了!在开发中,就当作优化吧!!
作者: t_joseph 时间: 2015-4-15 12:24
应该是考察查表的:)
作者: 猪猪fly侠 时间: 2015-5-6 09:18
不明觉厉
作者: 行意天下 时间: 2015-6-15 16:08
最后笔试,代码应该不会太多吧?
作者: 悦鹏 时间: 2015-6-29 15:51
厉害!得向你学习啊!
作者: 疯狂的小豆丁 时间: 2015-9-2 08:58
不错,学习了
作者: icm 时间: 2015-12-17 22:30
没看懂。。。
作者: zybnqf520 时间: 2016-2-22 20:39
可以的 赞个!!!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |