学习日记-C语言实现pat乙级1002(写出这个数)

学习日记-C语言实现pat乙级1002(写出这个数)

最终通过代码(1)

#include <stdio.h>
#include <malloc.h>

char* input(void);
int qsum(char* a);
void output(int t);

int main(void)
{
	char* num = input();
	int sum = qsum(num);
	free(num);
	output(sum);

	return 0;
}

char* input(void)
{
	char* num = (char*)malloc(100);
	scanf("%s", num);
	return num;
}
int qsum(char* num)
{
	int sum = 0;
	for (int i = 0; i < strlen(num); i++)
	{
		sum += num[i] - 48;
	}

	return sum;
}
void output(int t)
{
	char* py[10] = { "ling","yi","er","san","si","wu","liu","qi","ba","jiu" };
	int baiwei = 0, shiwei = 0, gewei = 0;
	if (t >= 100)
	{
		gewei += t % 10;
		t /= 10;
		shiwei += t % 10;
		t /= 10;
		baiwei = t;
		printf("%s ", py[baiwei]);
		printf("%s ", py[shiwei]);
		printf("%s", py[gewei]);

	}
	else if (t >= 10)
	{
		gewei += t % 10;
		t /= 10;
		shiwei = t;

		printf("%s ", py[shiwei]);
		printf("%s", py[gewei]);
	}
	else
	{
		printf("%s", py[t]);
	}
}

为了让代码更加整洁,增强程序可读性,用了三个函数,但是耗时却增加了。。

三个函数最后一个版本

最终通过代码(2)

#include <stdio.h>
void input(int * input)
{
	scanf("%s", input);
}
int main(void)
{
	char num[100];
	input(num);

	int n =strlen(num);

	char sum[100];
	int i;
	int output = 0;
	for (i=0;i<n;i++)
	{
		sum[i] = num[i]-48;
		output += sum[i];
	}

	char* py[10] = { "ling","yi","er","san","si","wu","liu","qi","ba","jiu" };
	int gewei = 0, shiwei = 0, baiwei = 0;

	if (output > 100)
	{
		gewei += output % 10;
		output /= 10;
		shiwei = output % 10;
		output /= 10;
		baiwei += output;

		printf("%s ", py[baiwei]);
		printf("%s ", py[shiwei]);
		printf("%s", py[gewei]);

	}

	else if (output >= 10)
	{
		gewei += output % 10;
		output /= 10;
		shiwei = output;

		printf("%s ", py[shiwei]);
		printf("%s", py[gewei]);
	}
	else
	{
		gewei = output;
		printf("%s", py[gewei]);
	}
	return 0;
}

因为想的模块化就想分为三部分,输入,运算操作,输出;

但只写了一个输入函数,发现其它不太好写就先没写,不过只写一个还不如不写。

第一版本

未通过代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
#include <string.h>

char tiqu(char ch)
{
	int a;
	//printf("%d", ch - 48);
	a = ch - 48;
	return a;
}

void output(int s)
{
	if (s == 0)
		printf("ling");
	else
	{
		int sum = 0;
		while (s) //这里是用的判断回文的方法,将数字倒过来。
		{
			sum = sum * 10 + s % 10;
			s /= 10;
		}
	//	printf("%d", sum);
		int a;
		while (sum > 0)
		{
			a = 0;
			a = a + sum % 10;
			switch (a)
			{
			case 1:
				printf("yi");
				break;
			case 2:
				printf("er");
				break;
			case 3:
				printf("san");
				break;
			case 4:
				printf("si");
				break;
			case 5:
				printf("wu");
				break;
			case 6:
				printf("liu");
				break;
			case 7:
				printf("qi");
				break;
			case 8:
				printf("ba");
				break;
			case 9:
				printf("jiu");
				break;

			}
			sum = sum / 10;

			if ((sum % 10) != 0 ) //发现每一个拼音后必须要有空格,但是最后一个还不能有空格,于是加了一个if语句
			printf(" ");
		}
		
		//printf("\b");//这是一开始没用if语句,为了把最后一个空格删掉,在最后加了一个退格的转义字符,但是在oj里不可行!
	}
}
int main(void)
{
	char input[100];
	scanf("%s", input);

	int i, n;
	int sum = 0;
	n = strlen(input);
	for (i = 0; i < n; i++)
	{
		sum += tiqu(input[i]);
	}
	//printf("%d\n", sum);
	output(sum);

	return 0;
}

未通过版本总结

这个版本是最先提交的版本,有一个检测点无法通过,扣一分;虽然扣一分,但错误很严重。

这个版本的bug是,求和以后,没有考虑要输出到“yi ling ling” “er ling”,101,100,10 等等这样的中间和末尾有零的数字!

一开始敲出来,用了%取余运算符,把数字一位一位的从个位依次取出。但是这样取出的数字是从个位开始,输入样例会出现wu san yi这样的情况,于是想到了用while判断回文数字的方法,把数字倒过来再从个位开始读取。

结果这样做会导致,本来100正确输出为yi ling ling,但倒过来成了001,输出就成了 “yi”

在参考他人代码和再次读题后发现:

题干中说明 n小于10的100次方,由这句可以得到两个结论:

1.输入数字的个数最多不大于100个数字;

2.每个数字是0~9

因为是将每一位数字相加之和,结合以上两个结论得出:

相加后的数字最大就是10*100-1,也就是999;意味着最多是三位数字,可以用个位,十位个位,百位十位个位表示;

总结体会

指针数组,字符串数组,这部分内容掌握不行!char* py[10] = { "ling","yi","er","san","si","wu","liu","qi","ba","jiu" };是写成这道题关键之一!

对与数据类型范围没有大概认知,一开始还用int和long long去存储样例输入;

解题思路

1.输入数字

(1).以字符串的格式输入数字;

(2).存储于字符数组中;(会以'1' '2' '3' '4' '5' '6' '\0'这样一个字符一个字符末尾加\0存储,类似以%s输入hello,在字符数组中会成为'h' 'e' 'l' 'l' 'o' ‘\0’

2.运算操作(把每一位数字相加);

(1)将字符数组中保存的数字字符(图形)一个一个取出;用for循环取出,但不取出最后一个'\0'(用strlen()函数获取字符串长度(不计算空字符’\0’))

(2)相加(因为是以字符%s的形式输入,键盘输入0相当于输入的是十进制数字48,要转为真正的数字0要减去48)这里涉及到ascii码,例:图形1对应的ascii码是49

3.输出结果

(1)将相加的和分为三类1.百位十位个位,2.十位个位3.个位(用if…else if…else);

(2)将每一位取出并输出(注意:别忽略100,10的情况);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值