1002 写出这个数
想好好写一下这个题,因为一开始写了一百多行都没有写正确…
如果不想看那么多直接拉到最后看代码,但是也许我的解题过程会对你有帮助。
之前的思路:
用除10取余循环计算得到一个sum也就是各个数字的和,然后把sum倒转回来在除10取余得到一个一个数字(因为取余首先得到的输出是个位数,但是要先输出最高位数,我就先把它倒转过来再用这种方法),然后用一个switch case去把各个拼音写出来,在写一个小小的循环去调用那个swtich的同时判断是不是最后一个数字,看要不要空格。
这个思路错在哪里呢,最大的问题在于我始终是用数字再计算,但是我们可以看到,给出的样例,他的数字是非常大的,题目写了保证小于10^100次方,这是int和long int等都无法表示的范围,后来我还想过写一个大整数的类去保证能处理这么大的整数(之前学c++有过这么一个写大整数的类),但是看了一下代码是很长一坨的,用来做这个显然不太合理。在查怎么处理大整数的时候看到有人说可以用字符数组来出来,有了这个思路这道题就向后推了一推,大整数肯定是可以处理 了。但是我还是没有放弃我反转sum的思路,最后提交上去了,20分只得了19分。为什么呢?思考了一下,每次用这个反转的操作会存在一个问题,就是如果sum=10,用一个反转的话,得到的是1而不是01。这一点如果是字符数组的话好处理,但是一直在用整数运算的话就是不行的。或者不要把函数分开写,直接一遍得那个数一遍就开始输出拼音。如果用一个字符数组去反转用while倒过来这也是可以处理的。(这种思路也贴一个代码在后面)最后我没有选择用字符数组去倒过来输出,选择用了栈,他的特点很明确,后进先出,刚刚push,pop之后就满足要求,而且还可以顺便把空格怎么弄给判断了。
共识:输入都是用字符数组处理(因为大整数)
以下2.3种解法是满分的。
1.之前写的全部用整数反转,19分。
问题在于不能处理个位数是0的情况。
2.一边反转整数一边输出拼音(这是别人的代码,还有些不简洁的地方,我直接贴过来了)
可以解决末尾是0的问题,因为不用返回一个整数,0直接就输出ling了。
#include<iostream>
using namespace std;
int main()
{
char x[10000];
int s[10000];
int y[10000];
int g = 0;
int sum = 0;
cin >> x;
for (int i = 0; x[i] != '\0'; i++)
{
s[i] = x[i] - 48;
sum += s[i];
}
if (sum == 0)
cout << "ling";
else
{
while (sum != 0)
{
int k;
k = sum % 10;
y[g++] = k;
sum = sum / 10;
}
}
for (int i = g - 1; i >= 0; i--)
{
switch (y[i])
{
case 0:if (i != 0)cout << "ling" << " ";
else cout << "ling"; break;
case 1:if (i != 0)cout << "yi" << " "; else cout << "yi"; break;
case 2:if (i != 0)cout << "er" << " "; else cout << "er"; break;
case 3:if (i != 0)cout << "san" << " "; else cout << "san"; break;
case 4:if (i != 0)cout << "si" << " "; else cout << "si"; break;
case 5:if (i != 0)cout << "wu" << " "; else cout << "wu"; break;
case 6:if (i != 0)cout << "liu" << " "; else cout << "liu"; break;
case 7:if (i != 0) cout << "qi" << " "; else cout << "qi"; break;
case 8:if (i != 0)cout << "ba" << " "; else cout << "ba"; break;
case 9:if (i != 0)cout << "jiu" << " "; else cout << "jiu"; break;
}
}
return 0;
}
3.用栈处理,这时候如果有0还是一个一个原封不动的push进去了。
不过我也是一边用栈一边输出,这样其实和上面那种没什么区别,用不着栈了,但也是一种思路
#include<iostream>
#include<string>
#include<stack>
using namespace std;
void print(int sum)
{
string name[] = { "ling","yi","er","san","si","wu","liu","qi","ba","jiu" };
stack<int>r_sum;
while (sum > 0)
{
r_sum.push(sum % 10);
sum /= 10;
if (sum == 0)
{
while (!r_sum.empty())
{
cout<<name[r_sum.top()];
r_sum.pop();
if (!r_sum.empty())
{
cout << " ";
}
}
}
}
}
int main()
{
char ch;
int sum = 0;
while ((ch = getchar()) != '\n')
{
sum = sum + ch - '0';
}
print(sum);
}
4.无比简洁的大神做法,只用了是十多行(这个代码也是别人那里贴过来的)
(但这种方法我去提交的时候是0分,提示的是编译错误。看逻辑是没有问题的,在我的编译器上也是完美运行)
前面的代码写这么多主要还是为了处理取余输出的问题,这个就不一样了,直接用了一个sprinf,作用就是把sum里面的数字一位一位的剥离出来,存在一个字符数组里面,等下就直接输出了。
大神把库函数用起来得心应手啊,就像现实生活中的阅历一样,只有厉害两字可说。
#include <iostream>
using namespace std;
int main()
{
int sum = 0;
char ch, s[4]; //ch作为临时变量保存输入的每一个字符,s保存sum的每一个数字 ,因为题目小于1000
char b[10][5] = { "ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu" };
while ((ch = getchar()) != '\n') //如果一直输入字符,不按回车的话
sum += (ch - '0');
sprintf_s(s, "%d", sum); // sprintf(char *buffer, const char *format,[ argument])将任意类型数据按某种格式转换成字符串
for (int i = 0; s[i] != 0; i++) {
if (i > 0) //消除第一个空格
printf(" ");
printf("%s", b[s[i] - '0']);
}
return 0;//上文sprintf中s为s[4]数组名,将sum的值存放在s中
}