[PAT-A 1082]Read Number in Chinese

在这里插入图片描述
题目大意:
按中文的发音规则输出一个绝对值在9以内的整数。
如果在数字的某节(个节,万节,亿节)中,某个非0位的高位为(千位除外),需要在非0位的发音前额外发音一个0。

思路:
1.将数字以字符串方式处理。
如123456789,则可以分为三个节,其中亿节为1,万节为2345,个节为6789。
2.关于节之间的划分:
1)设置下标left和right来处理一个节的输出,令left指向需要输出的位,right指向同节的各位。
2)初始时,另left=0,right=len-1(分别指向首尾)。如上例,left=0,right=8
判断left与right之间的数字个数,即right-left,如果>=4,则说明两端之间不止一个节,令right=right-4,一直到right-left<4
做完上述操作,left指向本节最高位,right指向本节最低位。
每处理一位,left++,向后移动一位,直至left>right,令right+=4表示该处理下一个节
3.关于节内的操作
1)关于0的处理,使用bool类型变量flag判断是否存在累计的0,初值为flase,当输出left指向的位之前,先判断该位是否位0,如果为0,则令flag=true
如果非0,则根据flag判断是否需要输出额外的0,若为true则输出0。 (如果本节内一直都是0就什么都不输出,下一节重新判断,重新令flag=false)
2)如果本位非零,检查flag,如果等于true,则表示之前有累积的零,先输出零,再输出本位,如1080, 则在遍历到8的时候前面有累积的0,要先输出零,在输出八十,即一千零八十。同时令isPrint=true表示本节输出过字符。
3)根据right与left的差值输出本位(不为0)的单位,如right-left=3,则输出qian,以此类推,left=right时表示此时处理为个位,不输出。
4)处理完一位,令left++,向后移动一位,如果大于right,进入下一节处理
3.关于节之间的操作
1)定义bool类型变量isPrint,来保存本节内是否有输出过数字,(如果都位0就不输出)初值flase,isPrint==true时表示输出过。
2)如果节内出现了不为0的数字,输出之后令isPrint=true。
3)在本节处理完之后,判断两个值,一是isPrint,二是right
当isPrint=true时表示本节有输出,当right!=len-1时表示此时处理的不是个节(因为个节不需要输出单位,只有亿与万需要)
两个条件都满足时,输出对应的亿或万,(根据right的数值判断)

AC代码:

#include<cstdio>
#include<cstring>
using namespace std;
char num[10][5] = { "ling","yi","er","san","si","wu","liu","qi","ba","jiu" };
char wei[5][5] = { "Shi","Bai","Qian","Wan","Yi" };
int main() {
	char str[15];
	(void)scanf("%s", str);
	int len = strlen(str);
	int left = 0, right = len - 1;//right与left分别指向字符串首尾元素,left指向要输出的位,right指向与left同节的个位
	if (str[0] == '-') {//如果为负数,则输出“Fu”,并把left右移一位
		printf("Fu");
		left++;
	}
	while (left + 4 <= right) {
		right -= 4;//right每次左移四位,直到left与right在同一节
	}
	while (left < len) {//每次循环处理数字的一节
		bool flag = false;//flag==false表示没有积累的0
		bool isPrint = false;//isPrint==flase表示该节没有输出过其中的位
		while (left <= right) {//从左至右处理数字中某节的每一位
			if (left > 0 && str[left] == '0') {//如果当前位为0且不是首位令flag=true
				flag = true;
			}
			else {//如果当前位不为0,则判断是否有累积的0
				if (flag == true) {
					printf(" ling");
					flag = false;
				}
				if (left > 0)printf(" ");//只要不是首位,每一位之前都要输出空格
				printf("%s", num[str[left] - '0']);
				isPrint = true;//isPrint==true表示本节存在输出过的数字,则需要在节之后输出单位
				if (left != right) {//如果left==right表示此时该输出各位,不需要输出单位,跳过
					printf(" %s", wei[right - left - 1]);
				}
			}
			left++;//left右移一位
		}
		if (isPrint == true && right != len - 1) {//当len-1==right时表示此时处理的为个节,不需要输出
			printf(" %s", wei[(len - 1 - right) / 4 + 2] );
		}
		right += 4;
	}
	return 0;
}
发布了101 篇原创文章 · 获赞 1 · 访问量 2988

猜你喜欢

转载自blog.csdn.net/weixin_44699689/article/details/104153284