赵大宝的博客

Program Artist

中文数字转阿拉伯数字

这个题与LeetCode第13题罗马数字转换很相似 13. Roman to Integer

我开始想用C++处理,进行汉字“个十百千万”与数字的对应,但是中文字符不属于ASCII码,直接使用标准类模板里的string会导致汉字乱码。

所以得使用宽字符串wstring和宽字符wchar_t

使用STL中的map容器保存汉字数字与阿拉伯数字的映射关系

然后就是从到右进行汉字数字的读取了

1、C++对汉字的处理:wstring 、wchar_t、wcin、wcout

wstring test;//定义宽字符串
wcin >> test;//输入:华师
wcout << test << endl;//输出:华师

但是在代码中定义宽字符时需要指定本地的系统区域locale

wcout.imbue(locale("chs"));//指定系统区域设置,chs为中国
wstring test1 = L"华师";//宽字符串前面需要加 L
wcout << test1 << endl;//输出华师

2、字符串数组的定义与初始化

其中我用了一个宽字符串数组wstring testdict[]保存我的测试用例,进行大小定义时候可以动态定义或者自定义,不过自定义的大小不能小于赋值的个数

string testdict[] = { "abc", "lkj" ,"dfgdf" ,"fgjghjg" };
//等价于
string testdict[4] = { "abc", "lkj" ,"dfgdf" ,"fgjghjg" };

但是定义为:

string testdict[3] = { "abc", "lkj" ,"dfgdf" ,"fgjghjg" };//将导致编译错误

也可以定义为:

string testdict[5] = { "abc", "lkj" ,"dfgdf" ,"fgjghjg" };
//其中testdict[4]将为""

3、获取字符串数组的大小:size()与sizeof

在进行for循环挨个取出测试用例时候需要知道数组的大小,我开始使用了testdict->size()这一方法,但是却发现获取的大小不对,才发现testdict->size()这一方法返回的大小与数组中第一个元素的长度相同

要想获得数组的大小需使用sizeof,C++中用类模板可以方便的构造一个函数获取数组大小

template <class T>
int getArrayLen(T& array)
{//使用模板定义一 个函数getArrayLen,该函数将返回数组array的长度

    return (sizeof(array) / sizeof(array[0]));
}
string testdict[] = { "ab", "lk123" ,"dfgdf6" ,"fgjghjg8" };
cout << getArrayLen(testdict) << endl;//4
cout << testdict->size() << endl;//2
cout << testdict->length() << endl;//2
cout << testdict[0].length() << endl;//2
cout << testdict[0].size() << endl;//2
cout << testdict[1].length() << endl;//5
cout << testdict[1].size() << endl;//5

在C中可以使用宏定义

#include <stdio.h>
#include <stdlib.h>

//定义一个带参数的 宏,将数组长度存储在变量len中
#define GET_ARRAY_LEN(array,len){len = (sizeof(array) / sizeof(array[0]));}

int main()
{
    char a[] = { 'a','2','3','d' };
    int len;
    GET_ARRAY_LEN(a, len)  //调用预定义的宏,取得数组a的长度,并将其存储在变量len中
    printf("%d\n", len);
    system("pause");
    return 0;
}

参考:https://blog.csdn.net/bopzhou/article/details/6063163

4、c++中 0 为NULL

突然发现c/c++中对整数0的处理时将0视为NULL

printf("%d", (0==NULL));//C:1,0==NULL为true
cout<<(0==NULL)<<endl;//cpp:1,0==NULLtrue

在C++11的标准中加了一个用来表示空指针的常量值——nullptr

在C中表示空指针的宏NULL是这样定义的:

#define NULL ((void *)0)

这样就可以表示空指针的,但是在C++中这个宏是不可以的,因为C++的类型检查比C更严格,不允许把void *类型的指针赋给指针变量,因此在C++中宏NULL是这样定义的:

#ifndef NULL
    #ifdef __cplusplus
        #define NULL 0
    #else
        #define NULL ((void *)0)
    #endif
#endif

显然,在C++中NULL的值和0是等价的。然而这就引发了一个严重的重载问题,例如下面两个函数:

void fun(int a, int *b);
void fun(int a, int b);

如果我问程序中有如下调用:

int a = 0;
fun(a,NULL);

可以看出我们想调用的是:void fun(int a, int *b);但实际上我们调用的是第二个函数。

而C++11中添加的nullptr就可以解决这个重载问题,减少很多不必要的BUG,编译环境允许的话,还是多多使用nullptr吧。


最终完整 中文数字转阿拉伯数字CPP代码:

#include <iostream>
#include <map>
#include <string>
using namespace std;

int chineseNum2num(wstring s)
{
    map<wchar_t, int> chineseNum;
    chineseNum.insert(pair<wchar_t, int>(L'零', 0));
    chineseNum.insert(pair<wchar_t, int>(L'一', 1));
    chineseNum.insert(pair<wchar_t, int>(L'二', 2));
    chineseNum.insert(pair<wchar_t, int>(L'三', 3));
    chineseNum.insert(pair<wchar_t, int>(L'四', 4));
    chineseNum.insert(pair<wchar_t, int>(L'五', 5));
    chineseNum.insert(pair<wchar_t, int>(L'六', 6));
    chineseNum.insert(pair<wchar_t, int>(L'七', 7));
    chineseNum.insert(pair<wchar_t, int>(L'八', 8));
    chineseNum.insert(pair<wchar_t, int>(L'九', 9));
    chineseNum.insert(pair<wchar_t, int>(L'十', 10));
    chineseNum.insert(pair<wchar_t, int>(L'百', 100));
    chineseNum.insert(pair<wchar_t, int>(L'千', 1000));
    chineseNum.insert(pair<wchar_t, int>(L'万', 10000));
    chineseNum.insert(pair<wchar_t, int>(L'亿', 100000000));
    chineseNum.insert(pair<wchar_t, int>(L'壹', 1));
    chineseNum.insert(pair<wchar_t, int>(L'贰', 2));
    chineseNum.insert(pair<wchar_t, int>(L'叁', 3));
    chineseNum.insert(pair<wchar_t, int>(L'肆', 4));
    chineseNum.insert(pair<wchar_t, int>(L'伍', 5));
    chineseNum.insert(pair<wchar_t, int>(L'陆', 6));
    chineseNum.insert(pair<wchar_t, int>(L'柒', 7));
    chineseNum.insert(pair<wchar_t, int>(L'捌', 8));
    chineseNum.insert(pair<wchar_t, int>(L'玖', 9));
    chineseNum.insert(pair<wchar_t, int>(L'拾', 10));
    chineseNum.insert(pair<wchar_t, int>(L'玖', 100));
    chineseNum.insert(pair<wchar_t, int>(L'仟', 1000));
    chineseNum.insert(pair<wchar_t, int>(L'萬', 10000));
    chineseNum.insert(pair<wchar_t, int>(L'億', 100000000));

    int result=0, tmp = 0, hnd_mln=0;
    wchar_t curr_char;
    int curr_digit;
    for (int i = 0; i < s.length(); ++i)
    {
        curr_char = s.at(i);
        if (chineseNum.find(curr_char) == chineseNum.end())
            return NULL;
        curr_digit = chineseNum.at(curr_char);

        if (curr_digit == pow(10, 8))//meet 「亿」 or 「億」
        {
            result = result + tmp;
            result = result * curr_digit;
            //get result before 「亿」 and store it into hnd_mln
            //reset `result`
            hnd_mln = hnd_mln * pow(10, 8) + result;
            result = 0;
            tmp = 0;
        }
        else
        {
            if (curr_digit == pow(10, 4))//meet 「万」 or 「萬」
            {
                result = result + tmp;
                result = result * curr_digit;
                tmp = 0;
            }
            else
            {
                if (curr_digit >= 10)//meet 「十」, 「百」, 「千」 or their traditional version
                {
                    if (tmp == 0)
                        tmp = 1;
                    result = result + curr_digit * tmp;
                    tmp = 0;
                }
                else
                {
                    tmp = tmp * 10 + curr_digit;
                    /*if (curr_digit != NULL)

                    else
                    {
                        return result;
                    }*/
                }
            }
        }
    }
    result = result + tmp;
    result = result + hnd_mln;
    return result;
}

template <class T>
int getArrayLen(T& array)
{//使用模板定义一 个函数getArrayLen,该函数将返回数组array的长度
    return (sizeof(array) / sizeof(array[0]));
}


int main()
{
    wcout.imbue(locale("chs"));
    wstring testdict[] = { L"哈十八",L"五十八", L"一百二十三万四千五百六十七" ,L"三千二百一十万零二百一十五" ,L"一亿零九十万零七十六" };
    for (int i = 0; i < getArrayLen(testdict); ++i)
    {
        wcout << testdict[i] << '\t' << chineseNum2num(testdict[i]) << endl;
    }
    system("pause");
    return 0;
}

这里写图片描述

同时也给出中文数字转阿拉伯数字Python3代码,Python3中字符统一为Unicode编码,没有那么多烦恼:中文数字2阿拉伯数字.py

参考:
用 Python 将中文数字转换成阿拉伯数字

阅读更多

扫码向博主提问

去开通我的Chat快问

u010412858

非学,无以致疑;非问,无以广识
  • 擅长领域:
  • 推荐系统
  • 机器学习
  • 数据挖掘
  • Python
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010412858/article/details/80354996
想对作者说点什么? 我来说一句

中文数字转换为阿拉伯数字

2017年08月11日 4KB 下载

没有更多推荐了,返回首页

不良信息举报

中文数字转阿拉伯数字

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭