1002 写出这个数

想好好写一下这个题,因为一开始写了一百多行都没有写正确…
如果不想看那么多直接拉到最后看代码,但是也许我的解题过程会对你有帮助。
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的情况。
1002 写出这个数

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里面的数字一位一位的剥离出来,存在一个字符数组里面,等下就直接输出了。
大神把库函数用起来得心应手啊,就像现实生活中的阅历一样,只有厉害两字可说。
1002 写出这个数

#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中 
}