2014年9月16日,美团网南京笔试题之一。原要求是输入整数的位数最多为四位,这里扩展为12为,即最高到千亿级别。
思路及步骤:
1 判别输入是否合法,并过滤字符串最前面的‘0’。
2 将字符串划分成四位一组的形式,其中每一组四位整数的输出方式相同。如20402040,其前四位和后四位都是2040,都输出“二千零四十”,只不过前四位要添上‘万’字而已。
3 将8~12位、4~8位、0~4位的数字分成三种情况输出
另外:形如10230401,应读为:“一千零二十三零四百零一”,所以在每输出完一组数字后,应考察下一组的首位是否为0,视情况输出‘零’。
下面是实现代码:
char *arrayOfDigit[10] = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" };
char *arrayOfIndex[7] = { "", "", "十", "百", "千", "万", "亿" };
void printGroupOf4(char *pStart, char *pEnd)
{
int index = pEnd - pStart + 1; // 确定位数,用于在数字后添加“十、百、千”
// 过滤字符串最前面的‘0’
while (pStart <= pEnd && *pStart == '0'){
++pStart;
--index;
}
// 此时pStart可能“所处位置”与“字符串对应的形式”:千位(yxxx)、百位(0yxx)、十位(00yx)、个位(000y),
// 或者直接退出(0000),其中y表示非零的整数,x表示未知的整数
while (pStart <= pEnd && *pStart != '0'){
cout << arrayOfDigit[*pStart - '0'] << arrayOfIndex[index];
++pStart;
--index;
if (pStart > pEnd){
return;
}
}
// 设置标记,确定是否应该输出‘零’
bool flag = false;
while (pStart <= pEnd && *pStart == '0'){
++pStart;
--index;
flag = true;
}
if (flag == true && pStart <= pEnd)
cout << arrayOfDigit[0];
// 打印最后面的转换后的字符串序列。此时pStart,要么到达非零的十位,要么直接到达了个位
while (pStart <= pEnd && *pStart != '0'){
cout << arrayOfDigit[*pStart - '0'] << arrayOfIndex[index];
++pStart;
--index;
if (pStart > pEnd){
return;
}
}
}
void digitToChinese(char *pStr)
{
if (!pStr)
return;
int numberLength = strlen(pStr);
// 检查符号位
if (pStr[0] == '-'){
cout << "负";
++pStr;
--numberLength;
}
else if (pStr[0] == '+'){
++pStr;
--numberLength;
}
// 过滤字符串前面的0
while (*pStr == '0'){
++pStr;
--numberLength;
}
// 检查后面的数字是否合法
for (int i = 0; i<numberLength; ++i){
if (pStr[i] > '9' || pStr[i] < '0')
{
cout << "输入字符串不合法!" << endl;
return;
}
}
// 当输入为0时
if (numberLength == 0){
cout << arrayOfDigit[0];
return;
}
if (numberLength > 12){
cout << "输入数字超出表示范围(千亿级)" << endl;
return;
}
// 处理前四位
if (numberLength > 8){
printGroupOf4(pStr, pStr + numberLength - 9);
cout << arrayOfIndex[6];
if (*(pStr + numberLength - 8) == '0') // 千万位为0
cout << arrayOfDigit[0];
pStr = pStr + numberLength - 8;
numberLength = 8;
}
// 处理中间四位
if (numberLength > 4){
printGroupOf4(pStr, pStr + numberLength - 5);
cout << arrayOfIndex[5];
if (*(pStr + numberLength - 4) == '0') // 千位为0
cout << arrayOfDigit[0];
pStr = pStr + numberLength - 4;
numberLength = 4;
}
// 处理最后四位
printGroupOf4(pStr, pStr + numberLength - 1);
}
int main(void)
{
char p[20];
cout << "请输入小于12位的数字:" << endl;
cin >> p;
digitToChinese(p);
return 0;
}