数字和汉字的相互转换

ublic class NumberFormat {

    private static String[] chinese = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
    private static String[] replace = {"|〇", "|壹", "|贰", "|叁", "|肆", "|伍", "", "", "", ""};
    private static Hashtable<Character, Long> digits = new Hashtable();
    private static String[] commonDigit = {"", "十", "百", "千"};
    private static String[] twiceDigit = {"万", "亿", "兆"};

    static {
        digits.put('十', 10L);
        digits.put('百', 100L);
        digits.put('千', 1000L);
        digits.put('万', 10000L);
        digits.put('亿', 100000000L);
        digits.put('兆', 10000000000000000L);
    }

    /**
     * 可用于处理年份(如二〇一六)及多位数字
     * 若需添加错字验证,可在replace中对应位置放置;以|隔开
     * 若需添加更高位运算,请在digits中put相应元素,并注意修改long
     *
     * @param chineseNum
     * @return
     */
    public static String parse(String chineseNum) {

        for (int i = 0, len = chinese.length; i < len; i++) {
            chineseNum = chineseNum.replaceAll(chinese[i] + replace[i], Integer.toString(i));
        }
        if (chineseNum.matches("[0-9]+")) {
            return chineseNum;
        }
        //十六处理为一十六
        if ("十".equals(chineseNum.substring(0, 1))) {
            chineseNum = "1".concat(chineseNum);
        }
        char[] cNums = chineseNum.toCharArray();
        return getNum(cNums);
    }

    /**
     * 算法思路:
     * 倒序累加数字乘以其叠加倍数,
     * 如3千8百万亿中,
     * 3的叠加倍数(multi)是一千万亿,当前倍数(current)是一千,基数(base)是一万亿
     * 8的叠加倍数       是一百万亿,当前倍数         是一百,基数      是一万亿
     *
     * @return
     */
    private static String getNum(char[] cNums) {
        long sum = 0, multi = 1, current, last = 1, base = 1;
        for (int i = cNums.length - 1; i >= 0; i--) {
            if (cNums[i] > '9') {
                current = digits.get(cNums[i]);
                //当前倍数比基数大,则更新叠加倍数和基数为当前倍数
                if (current > base) {
                    base = current;
                    current = 1;
                } else {
                    base = getBase(current, last, base);
                }
                multi = current * base;
                last = current;
            } else {
                sum += (cNums[i] - '0') * multi;
            }
        }
        return String.valueOf(sum);
    }

    /**
     * 如果当前倍数突然比上个倍数少,说明已进入到上个倍数的子倍数
     * 则更新叠加倍数为上个倍数
     * <p>
     * 比较基数和上个倍数
     * 基数>上个倍数时(如三百万亿,读取到百时,base(亿)>last(万))
     * 则更新基数为万亿
     * 基数<上个倍数时(如三十亿零六十万,
     * 读取到十时进入,last(万)>base(1),更新基数为万
     * 读取到十时再次进入,last(亿)>base(万),更新基数为亿
     *
     * @return
     */
    private static long getBase(long current, long last, long base) {
        if (current < last) {
            base = base > last ? base * last : last;
        }
        return base;
    }

    /**
     * 将阿拉伯数字转换为中文
     *
     * @param number
     * @return
     */
    public static String format(long number) {
        //千以上位计数器
        int[] twiceDigitCounter = new int[twiceDigit.length];
        String numStr = simpleFormat(number);
        //{三,零,零,零,零,五}
        char[] nums = numStr.toCharArray();
        StringBuffer addDigit = new StringBuffer(nums.length * 2);
        int index = 0;
        boolean appendZero = false;
        //倒序装载十百千,若遇千位以上,特殊处理(getDigitByCounter)
        for (int i = nums.length - 1; i >= 0; i--) {
            if (appendZero && lastIsNum(addDigit)) {
                addDigit.append("零");
                appendZero = false;
            }
            if (index == commonDigit.length) {
                String current = getDigitByCounter(twiceDigitCounter);
                String last = getLast(addDigit);
                if (indexOf(last) < indexOf(current)) {
                    addDigit.delete(addDigit.length() - 1, addDigit.length());
                }
                addDigit.append(current);
                index = 0;
            }
            if (nums[i] == '零') {
                appendZero = true;
            } else {
                if (index != commonDigit.length) {
                    addDigit.append(commonDigit[index]);
                }
                addDigit.append(nums[i]);
            }
            index++;

        }
        return addDigit.reverse().toString();
    }

    /**
     * 200173518 简单转换为 二零零一七三五一八
     *
     * @param number
     * @return
     */
    private static String simpleFormat(long number) {
        String numStr = String.valueOf(number);
        for (int i = 0, len = chinese.length; i < len; i++) {
            numStr = numStr.replaceAll(Integer.toString(i), chinese[i]);
        }
        return numStr;
    }

    /**
     * 转换为中文的年
     */
    public static String getChineseNumYear(long number) {
        if (number < 2000 || number > 2100) {
            System.out.println("日期格式错误");
            return null;
        }
        return simpleFormat(number);
    }

    /**
     * 万出现两次则为亿,亿出现两次则为兆
     * 因此,千位以上从万计数,
     * 若万没出现过,则为万。
     * 若万出现过,则置万为没出现过,进位到亿
     *
     * @return
     */
    private static String getDigitByCounter(int[] twiceDigitCounter) {
        for (int i = 0, len = twiceDigit.length; i < len; i++) {
            if (twiceDigitCounter[i] == 0) {
                twiceDigitCounter[i] = 1;
                return twiceDigit[i];
            } else if (twiceDigitCounter[i] == 1) {
                twiceDigitCounter[i] = 0;
            }
        }
        twiceDigitCounter[0] = 1;
        return twiceDigit[0];
    }

    /**
     * 得到最后一位
     *
     * @param addDigit
     * @return
     */
    private static String getLast(StringBuffer addDigit) {
        if (addDigit.length() == 0) {
            return null;
        }
        return addDigit.substring(addDigit.length() - 1);
    }

    /**
     * 万亿兆。。。的位置
     *
     * @param digit
     * @return
     */
    private static int indexOf(String digit) {
        for (int i = 0, len = twiceDigit.length; i < len; i++) {
            if (twiceDigit[i].equals(digit)) {
                return i;
            }
        }
        return twiceDigit.length;
    }

    /**
     * 最后一位是否为非零数字(不可为万/亿等计位符)
     *
     * @param addDigit
     * @return
     */
    private static boolean lastIsNum(StringBuffer addDigit) {
        String last = getLast(addDigit);
        for (int i = 1, len = chinese.length; i < len; i++) {
            if (chinese[i].equals(last)) {
                return true;
            }
        }
        return false;
    }


    public static void main(String[] args) {
        //测试年份及错别字
        System.out.println(NumberFormat.parse("贰〇一八"));
        System.out.println(NumberFormat.parse("三十亿零四十万"));
        System.out.println(NumberFormat.parse("九千万零一"));
        System.out.println(NumberFormat.parse("三百万亿"));
        System.out.println(NumberFormat.parse("一百二十三兆四千五百六十七万八千九百零一亿二千三百四十五万六千七百八十九"));

        System.out.println(NumberFormat.getChineseNumYear(2018));
        System.out.println(NumberFormat.format(3000400000L));
        System.out.println(NumberFormat.format(90000001));
        System.out.println(NumberFormat.format(300000000000000L));
        System.out.println(NumberFormat.format(1234567890123456789L));

    }
}

 

在C#中,可以使用以下方法将中文汉语数字和阿拉伯数字相互转化。 1. 将阿拉伯数字转换为中文汉语数字: 可以使用一个方法,将阿拉伯数字的每一位转换为对应的中文数字。例如,可以创建一个方法`OneBitNumberToChinese`,将数字1-9转换为中文数字。然后,可以根据阿拉伯数字的位数,逐位转换为中文数字,并拼接起来。\[1\] 2. 将中文汉语数字转换为阿拉伯数字: 可以使用一个方法,将中文汉语数字的每一位转换为对应的阿拉伯数字。可以创建一个方法`FFXieshu`,接受中文汉语数字作为参数,并返回对应的阿拉伯数字。该方法可以处理整数、小数、正数、负数等情况。\[2\]\[3\] 需要注意的是,转换中文汉语数字和阿拉伯数字时,要考虑到数字的位数、小数点、计数单位等情况,以确保转换结果的准确性。 以下是一个示例代码,演示了如何在C#中实现中文汉语数字和阿拉伯数字相互转化: ```csharp public class ChineseNumberConverter { private static string\[\] chineseDigits = { "〇", "一", "二", "三", "四", "五", "六", "七", "八", "九" }; private static string\[\] arabicDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; public static string ArabicToChinese(int number) { string chineseNumber = ""; string numberString = number.ToString(); foreach (char digit in numberString) { int digitValue = int.Parse(digit.ToString()); chineseNumber += chineseDigits\[digitValue\]; } return chineseNumber; } public static int ChineseToArabic(string chineseNumber) { string numberString = ""; foreach (char digit in chineseNumber) { int digitIndex = Array.IndexOf(chineseDigits, digit.ToString()); numberString += arabicDigits\[digitIndex\]; } return int.Parse(numberString); } } // 示例用法 int arabicNumber = 12345; string chineseNumber = ChineseNumberConverter.ArabicToChinese(arabicNumber); Console.WriteLine(chineseNumber); // 输出:一二三四五 string chineseNumber = "一二三四五"; int arabicNumber = ChineseNumberConverter.ChineseToArabic(chineseNumber); Console.WriteLine(arabicNumber); // 输出:12345 ``` 请注意,以上示例代码仅演示了基本的转换方法,实际应用中可能需要根据具体需求进行适当的修改和扩展。 #### 引用[.reference_title] - *1* [C# 实现阿拉伯数字转换为中文数字3种实现思路(递归拼接、循环拼接、if拼接)](https://blog.csdn.net/qq_38974638/article/details/108476401)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [汉语数字转换成阿拉伯数字](https://blog.csdn.net/ggggwhw/article/details/119961135)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值