算法--java实现将数字转换成人民币大写(迅雷面试题)

简介: 今天去迅雷面试,是个数字转换成人民币的算法题:public class Rmb { /** * 人民币的基本信息和操作 * * @author soyoungboy * @version 1.

今天去迅雷面试,是个数字转换成人民币的算法题:

public class Rmb {
    /**
     * 人民币的基本信息和操作
     *
     * @author soyoungboy
     * @version 1.0
     */
    private double number;     //人民币的数量
    private static final String[] hanArr = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};//汉字计数符号
    private static final String[] unitArr = {"", "拾", "佰", "仟"};//汉字计数单位
    private static final String[] unitArrs = {"万", "亿", "万", "兆", "万", "亿", "万", "圆"}; //顺序添加单位

    //private String[] unitsArr = {"万", "亿"}; //汉字计数大单位
    public Rmb() {
    }

    /**
     * 构造器初始化人民币数量
     *
     * @param number 给定的初始化人民币数
     */
    private Rmb(double number) {
        this.number = number;
    }

    /**
     * 把一个浮点数分解成long型部分和小数部分字符串,把人民币换成了整数,浮点数在取小数部分时临界值有误差
     *
     * @return 返回分解后的字符串数组,第一个数组元素是整数部分,第二个是小数部分字符串
     */
    private String[] divideNum() {
        double num = Math.round(number * 100);//对number进行四舍五入取整
        long integerPart = (long) num; //连同小数点后两位取成整数 ,避免使用减法
        //double decimalsPart = num-integerPart;//小数部分,临界时产生了误差
        String decimalsPartStr;
        long b = integerPart % 10; //小数点后第二位
        long a = (integerPart / 10) % 10;//小数点后第一位
        integerPart /= 100;
        if (a == 0 && b == 0) {
            decimalsPartStr = null;
        } else {
            decimalsPartStr = "" + a + b;
        }
        return new String[]{String.valueOf(integerPart), decimalsPartStr};
    }

    /**
     * 把一个数字字符转换成汉语的人民币读法
     *
     * @return 返回汉语人民币读法的字符串形式
     */
    private String toHanStr() {
        String[] results = new String[9]; //用来暂时存储每四位分段后的数字字符串
        String[] resultStrs = new String[9];//用来暂时存储每四位分段后转换成的人民币读法
        StringBuilder result = new StringBuilder();//最终的转换结果
        String[] divideStr = divideNum(); //得到浮点数分解成的long型部分和小数部分字符串,第一个数组元素是整数部分字符串,第二个是小数部分字符串
        results[8] = divideStr[1];
        for (int i = divideStr[0].length(), j = 8; i > 0 && j > 0; i -= 4, j--) {
            try {
                results[j - 1] = divideStr[0].substring(i - 4, i);
            } catch (Exception e) {
                results[j - 1] = divideStr[0].substring(0, i);
                break;
            }
        }
        if (results[8] == null) {
            resultStrs[8] = "整";
        } else if (results[8].charAt(1) == '0') {
            resultStrs[8] = hanArr[results[8].charAt(0) - 48] + "角"; //根据ASCII码和hanArr数组吧数字改成汉语大写
        } else {
            resultStrs[8] = hanArr[results[8].charAt(0) - 48] + "角" + hanArr[results[8].charAt(1) - 48] + "分";
        }
        for (int i = 0; i < 8; i++) {
            if (results[i] != null) {
                resultStrs[i] = "";
                resultStrs[i] += hanArr[results[i].charAt(0) - 48] + unitArr[results[i].length() - 1]; //根据ASCII码和数组长度选择数的单位
                for (int j = 1; j < results[i].length(); j++)
                    if (results[i].charAt(j - 1) == '0' && results[i].charAt(j) != '0')
                        resultStrs[i] += "零" + hanArr[results[i].charAt(j) - 48] + unitArr[results[i].length() - 1 - j];  //根据ASCII码和数组长度选择数的单位
                    else if (results[i].charAt(j) != '0')
                        resultStrs[i] += hanArr[results[i].charAt(j) - 48] + unitArr[results[i].length() - 1 - j];
            }
        }
        for (int i = 0; i < 8; i++) {
            if (resultStrs[i] != null) {
                result.append(resultStrs[i]).append(unitArrs[i]);
            }
        }
        result.append(resultStrs[8]);
        return result.toString();
    }

    public static void main(String[] args) {
        double l;
        byte[] bye = new byte[50];
        System.out.println("请输入要转换的人民币数量:");
        try {
            System.in.read(bye);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String s = new String(bye);
        l = Double.parseDouble(s);
        Rmb r = new Rmb(l);
        s = r.toHanStr();
        System.out.println(s);

    }
}

结果:

请输入要转换的人民币数量:
456789
肆拾伍万陆仟柒佰捌拾玖圆整

后悔没坚持参加面试。

如果code代码出处:https://www.teakki.com/p/57df787e1201d4c1629ba891

相关文章
|
1天前
|
XML 缓存 Java
Java大厂面试题
Java大厂面试题
4 0
|
1天前
|
存储 安全 Java
Java大厂面试题
Java大厂面试题
4 0
|
1天前
|
存储 安全 Java
Java大厂面试题
Java大厂面试题
4 0
|
2天前
|
安全 Java
就只说 3 个 Java 面试题 —— 02
就只说 3 个 Java 面试题 —— 02
13 0
|
2天前
|
存储 安全 Java
就只说 3 个 Java 面试题
就只说 3 个 Java 面试题
9 0
|
8天前
|
安全 算法 Java
深入理解Java并发编程:线程安全与性能优化
【4月更文挑战第11天】 在Java中,高效的并发编程是提升应用性能和响应能力的关键。本文将探讨Java并发的核心概念,包括线程安全、锁机制、线程池以及并发集合等,同时提供实用的编程技巧和最佳实践,帮助开发者在保证线程安全的前提下,优化程序性能。我们将通过分析常见的并发问题,如竞态条件、死锁,以及如何利用现代Java并发工具来避免这些问题,从而构建更加健壮和高效的多线程应用程序。
|
1天前
|
安全 Java
深入理解 Java 多线程和并发工具类
【4月更文挑战第19天】本文探讨了Java多线程和并发工具类在实现高性能应用程序中的关键作用。通过继承`Thread`或实现`Runnable`创建线程,利用`Executors`管理线程池,以及使用`Semaphore`、`CountDownLatch`和`CyclicBarrier`进行线程同步。保证线程安全、实现线程协作和性能调优(如设置线程池大小、避免不必要同步)是重要环节。理解并恰当运用这些工具能提升程序效率和可靠性。
|
2天前
|
安全 Java
java多线程(一)(火车售票)
java多线程(一)(火车售票)
|
2天前
|
安全 Java 调度
Java并发编程:深入理解线程与锁
【4月更文挑战第18天】本文探讨了Java中的线程和锁机制,包括线程的创建(通过Thread类、Runnable接口或Callable/Future)及其生命周期。Java提供多种锁机制,如`synchronized`关键字、ReentrantLock和ReadWriteLock,以确保并发访问共享资源的安全。此外,文章还介绍了高级并发工具,如Semaphore(控制并发线程数)、CountDownLatch(线程间等待)和CyclicBarrier(同步多个线程)。掌握这些知识对于编写高效、正确的并发程序至关重要。
|
2天前
|
安全 Java 程序员
Java中的多线程并发编程实践
【4月更文挑战第18天】在现代软件开发中,为了提高程序性能和响应速度,经常需要利用多线程技术来实现并发执行。本文将深入探讨Java语言中的多线程机制,包括线程的创建、启动、同步以及线程池的使用等关键技术点。我们将通过具体代码实例,分析多线程编程的优势与挑战,并提出一系列优化策略来确保多线程环境下的程序稳定性和性能。