因为复习java基础知识,碰到了阿拉伯数字转换成人民币的面试题,在网上搜索到了不少的相关内容,结果简单测试了下,就发现了很多BUG,为了避免面试时碰到这样的题目,我就自己分析琢磨了。思前想后弄了好久(我菜),弄出了这么个小程序。从应用的角度来看,应该是没有什么意义了啊,也就是和有类似需求的人交流交流了。如果有什么不对的地方,或者可以更好地实现的地方,或者更好的思路,算法什么的,请大家批评指正啊。我就是个小菜鸟,呵呵!
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Pattern;
public class ConvertMoney {
/**本人是菜鸟,彻彻底底的菜鸟,因为面试题,搜索网上的代码,结果发现有很多BUG
* 怕面试的时候真的遇到这样的题目,只好自己弄明白。琢磨了半天,最终成型。
*
*因为是菜鸟,所以基本的逻辑和思路都是比较简单的,如果您有更好的思路请留言
*
* 详细思路是这样的:
* 判断从控制台获得输入的字符串是否符合要求
* 分支:先判断是否输入,再判断是否是符合正则表达式的数字,再判断是否超出范围
* 符合要求返回精确到小数点后2位的字符串
* 把得到的字符串转换成人民币习惯的字符串
* 分支:先以"."为分隔符,把字符串拆分成 整数部分 + 小数部分
* 转换整数部分
* 转换小数部分
* 相加得到需要的人民币格式的字符串
*
* @author Peter Zhang
*/
private static final int SIZE = 16;
//最大为9999999999999.99 小于拾万亿
private final static String REGEX_NUM = "^\\d+(\\.\\d+)?$"; // 是数字
private final static String REGEX_DOUBLE = "^\\d{1,13}(\\.){1}\\d{0,2}$"; //最大为9999999999999.99的 double
private final static String REGEX_LONG ="\\d{1,13}";//最大为9999999999999 的long
private static final String CN_ZERO = "零";
private static final String CN_SYMBOL = "¥:";
private static final String CN_DOLLAR = "圆";
private static final String CN_INTEGER = "整";
private static final String[] DIGITS = new String[] { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
private static final String[] SMALLUNITS = new String[] { "", "拾", "佰", "仟" };
private static final String[] BIGUNITS = new String[] { "", "万", "亿", "万" };
private static final String[] DECIMALS = new String[] { "角", "分" };
// 测试
public static void main(String[] args) {
String num = getNum();//得到精确到小数点后两位的浮点数
String rmb = transToRMB(num);
System.out.println(rmb);
}
/**把阿拉伯数字转成人民币的写法输出
*
* @param num
* @return rmb
*/
private static String transToRMB(String num) {
String rmb = ""; //
if(Double.valueOf(num)==0.00){
rmb = CN_SYMBOL + CN_ZERO + CN_DOLLAR ;
return rmb;
}else{ //把浮点数拆分成 整数部分 + 小数部分
String integers = ""; //整数部分
String decimals = ""; //小数部分
String intOut = ""; //最终输出的整数部分
String decOut = ""; //最终输出的小数部分
String[] temp = num.split("\\."); //把num以"."为分隔符,分成两个String
integers = temp[0];
decimals = temp[1];
//转换整数部分
String intPart = "";
if(Double.parseDouble(integers)>0){ //最多13位 到万亿
int countZero =0;
for(int i=0;i<integers.length();i++){
//从左到右的每个字符
intPart = integers.substring(i,i+1);
int big = (integers.length() - i - 1) / 4 ;
int small = (integers.length() - i - 1 ) % 4 ;
if(intPart.equals("0")){
countZero++;
//处理 "[1-9]{1}0{12}" 12个0 的情况
if((integers.length()==13)&&(i==1)){
intOut += BIGUNITS[big];
}
}else{
if(countZero>0){
intOut += CN_ZERO;
}
countZero = 0;
intOut += DIGITS[Integer.parseInt(intPart)] + SMALLUNITS[small];
}
if(small==0 && countZero<4){
intOut += BIGUNITS[big];
}
}
intOut +=CN_DOLLAR;
}else{ // 整数部分为零
intOut += "";
}
//转换小数部分
String decPart = "";
if(Integer.parseInt(decimals)>0){ // 精确到两位 i只能是 0 和 1
//小数部分2位 有1 或者 2者都不为0
for(int i=0;i<decimals.length();i++){
//从左到右的每个字符
decPart = decimals.substring(i,i+1); //
if(!decPart.equals("0")){
decOut += DIGITS[Integer.parseInt(decPart)]+DECIMALS[i];
}else{
if(!intOut.equals("")){//整数部分不为零时,显示"零"
if(i==0){
decOut += CN_ZERO;
}
}
}
}
}else{ //都为0
decOut += CN_INTEGER ;
}
rmb = intOut + decOut;
return rmb;
}
}
/**
* 从命令行得到一个字符串,通过checkNum()方法检查是否符合要求
* @return 如果符合要求,则调用roundString()方法返回double;
* 否则,提示错误,返回-1
*/
private static String getNum(){
Scanner scan = new Scanner(System.in);
String input = null;
System.out.println( "请输入一个数字(最多到小数点后两位):");
input = scan.next();
scan.close();//关闭流
if(!checkNum(input)){
return "0";
}else{
return trimNum(input);
}
}
/**
* 把输入的数字精确为保留小数点后两位的浮点数,返回其字符串值
* @param input 通过checkNum()方法后的input
* @return bd2.toString
*/
private static String trimNum(String input) {
BigDecimal bd1 = new BigDecimal(input);
BigDecimal bd2 = bd1.setScale(2,BigDecimal.ROUND_HALF_UP);
return bd2.toString();
}
/**
* 验证输入是否符合要求(是Long 或者 Double 且长度不能超过16)
* @param input
* @return
*
*/
private static boolean checkNum(String input){
if(input==null||input.length()==0||input.trim().equals("")){
System.out.println("您没有输入");
return false;
}else{
boolean b = input.matches(REGEX_NUM);
// boolean b = Pattern.matches(REGEX, input);
if(!b){
System.out.println("您输入的不是一个数字");
return false;
}else{
if(input.length()>SIZE){
System.out.println("您输入的数字超出最大范围");
return false;
}else{
if(input.matches(REGEX_LONG)){ //符合long
return true;
}
if(!input.matches(REGEX_DOUBLE)){ //不符合精确到小数点后一位或两位的double
System.out.println("您输入的数字超出最大范围");
return false;
}
return true;
}
}
}
}
}
分享到:
相关推荐
阿拉伯数字金额转换成汉字金额,比如1000.00 转换成 壹仟元。
java教程书籍
JAVA菜鸟级入门教程
JAVA面试者题库,基本包含了JAVA新手面试的各个模块。
JAVA程序员 从笨鸟到菜鸟
这个是我一次c++作业的题目。我还是个菜鸟,做的还不好,希望高手们多多指点。。或者有人帮修改一下更好
java程序员由菜鸟到笨鸟 作者:曹胜欢
菜鸟一用就会,Java菜鸟专用很好很强大。
JAVA菜鸟级入门教程
java菜鸟学习第一步-java基础语法,学习一门语言先从语法开始学起,学好基础才能深入的学习编程
Java的培训教程,一步一步教你由菜鸟到高手 好东西共分享
Java的菜鸟教程,对Java的开发工具,环境配置都有详细的介绍,其内还包涵了Java开发的基础知识,内容很丰富。
runoob菜鸟教程的打包JAVA教程,非常好的资源,值得学习!
Java菜鸟技术PDF 江苏Java的一些技术 适合入门的孩子看看
菜鸟一枚,朋友需要在excel中将大写数字转换为阿拉伯数字,由于是文本格式的,我也不会,就研究用了vb来实现。当时想着复制粘贴,结果网上没找到,于是自己胡写了一些,一般情况测试通过。 这是vb源码。 普通excel...
菜鸟学习JAVA简单入门到精通,可以帮助刚入门的程序猿快速学习进入公司需要的技能
菜鸟教程网站上的Python3教程还挺详细,想在没有网络的电脑上离线看但是发现网上没有资源,只有老版本的PDF文档,实在不方便阅读,所以自己做了一个,Python3菜鸟教程离线版内部包含20200914保存的完整离线版教程...
Java中Scanner的一些用法; 练习代码用用,先来无聊看看。