正整数的中文读法(C++ Python)

基本思路

(1)数字到中文的映射

(2)每四位作为一个单元处理

(3)从简入手,逐步细化

映射

  • 中文读法中会出现的汉字如下:
    零;一、二、… 、九;十、百、千;万、亿

  • 零比较特殊,单独存储

  • 一、二、…、九是计数的基本数字,存为一个数组
  • 十、百、千是每个万组里面的单位,存为一个数组
  • 万、亿是更大单位,存为一个数组

基本处理

  • 通过循环得到正整数各个位的数字,数据保存到数组data[]中

  • 通过取模运算和除法运算,得到该数字所在万组的信息

  • 每个万组结束,加上万组的单位

  • 此时并未处理任何特殊情况

特殊情况“0”

  • 一个万组内,末尾的所有“0”不读,如200、2001234

  • 一个万组内,非零数字之间有“0”,只需要读一个“零”,如:201、3002、1050

  • 一个万组内,高位数字为“0”,如果还有更高的万组,那么“0”读出来,否则不读,如:0030、100300、

特殊情况“1”

  • 一个万组内,千位和百位都是“0”,十位为“1”时,而且没有更高的万组,“一”不读,如:14、123562

  • 如果有更高的万组,“一”需要读出来,如:20012

//c++
#include<iostream>
#define MAX 10
#define MID 4
#define MIN 3
using namespace std;
const string CHINESE_ZERO = "零";;
const string CHINESE_DIGITS[MAX] = { "", "一", "二", "三", "四", "五","六","七","八","九" };
const string CHINESE_UNITES[MID] = { "","十","百","千" };
const string CHINESE_LARGE_UNITES[MIN] = { "", "万","亿" };


class NumToCh
{
public:
    NumToCh(int num);
    ~NumToCh();
    void Translate();

private:
    int number;
    int data[MAX];
    int len;
    string word;

};

NumToCh::NumToCh(int num)
{


    this->number = num;

    int digit;
    int position=0;
    while (this->number>0)
    {
        digit = this->number % MAX;
        this->number = this->number / MAX;
        data[position] = digit;
        position += 1;
    }
    this->len = position;

}
void NumToCh::Translate()
{
    bool groupIsZero = true;
    bool needZero = false;
    int unite = 0;
    int grou = 0;

    for (int i = len-1; i >=0; i--)
    {
        unite = i % MID;
        grou = i / MID;
        if (this->data[i] != 0)
        {
            if (needZero) this->word.append(CHINESE_ZERO);

            if (this->data[i] != 1 || unite != 1 || (!groupIsZero) || (grou == 0 && needZero))
                this->word.append( CHINESE_DIGITS[this->data[i]]);

            this->word.append( CHINESE_UNITES[unite]);
        }

        groupIsZero = groupIsZero && this->data[i] == 0;

        if (unite == 0 && (!groupIsZero))
            this->word.append( CHINESE_LARGE_UNITES[grou]);

        needZero = (data[i] == 0 && (unite != 0 || groupIsZero));

        if (unite == 0)
            groupIsZero = true; 
    }

    for (int j = 0; j < this->word.length(); j++)
        cout << this->word[j];
    cout << endl;
}
NumToCh::~NumToCh()
{
}
int main()
{
    while (true)
    {
        int number=0;
        cout << "请输入一个10亿以内的正整数:";
        cin >> number;
        if (number == 0)
        {
            cout << "零" << endl;
            continue;
        }
        NumToCh num(number);
        num.Translate();
    }
    return 0;
}
#Python
#coding:utf-8
CHINESE_NEGATIVE = u'负'
CHINESE_ZERO = u'零'
CHINESE_DIGITS = [u'', u'一', u'二', u'三', u'四', u'五', u'六', u'七', u'八', u'九']
CHINESE_UNITS = [u'', u'十', u'百', u'千']
CHINESE_GROUP_UNITS = [u'', u'万', u'亿', u'兆']

def _enumerate_digits(number):
    """
    :type number: int|long
    :rtype: collections.Iterable[int, int]
    """
    position = 0
    while number > 0:
        digit = number % 10
        number //= 10
        yield position, digit
        position += 1

def translate_number_to_chinese():
    number = int(raw_input(u"请输入一个整数:"))
    group_is_zero = True
    need_zero = False
    words = []
    for position, digit in reversed(list(_enumerate_digits(number))):
        unit = position % len(CHINESE_UNITS)
        group = position // len(CHINESE_UNITS)

        if digit != 0:
            if need_zero:
                words.append(CHINESE_ZERO)

            if digit != 1 or unit != 1 or not group_is_zero or (group == 0 and need_zero):
                words.append(CHINESE_DIGITS[digit])

            words.append(CHINESE_UNITS[unit])

        group_is_zero = group_is_zero and digit == 0

        if unit == 0 and not group_is_zero:
            words.append(CHINESE_GROUP_UNITS[group])

        need_zero = (digit == 0 and (unit != 0 or group_is_zero))

        if unit == 0:
            group_is_zero = True

    for i in range(len(words)):
            print (words[i]),
    print

def main():
    while(True):
        translate_number_to_chinese()

if __name__ == '__main__':
    main()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

seakot

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值