这个题与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==NULL为true
在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