1082 Read Number in Chinese分数 25(适合新手,没用STL,c代码)

PAT (Advanced Level) Practice 1082 Read Number in Chinese

题意

按中文发音需明确如下规则:

1,在数字的某节中(如个节(千,百,十, 个),万节(千万,百万,十万,万), 亿节),

只要首位不是0, 但在后面非零位的前面有零位,那么需要在该非零位的发音前额外发音一个零,如8080 发音“ba qian ling ba shi”, 如8008发音“ba qian ling ba”, 10808发音“yi Wan ling ba Bai ling ba”。

2,每节的末尾要视情况输出万或者亿(个节除外)

对于102346789可以划分节:1, 0234, 6789(从右往左,每四位或小于四位为一节,依次为个节, 万节, 亿节)

思路

步骤1:先将数字按字符串方式处理,并且设置下标left和right来处理数字的每一个节(个节, 万节, 亿节)的输出,即令left指向当前需要输出的位,right指向与left同节的个位

步骤2:在需要输出的每一个节中,需要解决的问题是如何处理额外发音的零,采用规则1来设计:

设置bool型变量flag表示当前是否存在累积的零。当输出left指向的位之前,先判断该位是否为0:如果为0,则令flag为true,表示存在累积的0;如果非0,则根据flag的值来判断是否需要输出额外的零。

此后,就可以输出该位本身以及该位对应的位号(十,百,千)。

而当整一小节处理完毕后,再输出 万或者亿

#include <cstdio>
#include <cstring>
char numb[10][5] {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
char post[][5] = {"", "Shi", "Bai", "Qian", "Wan", "Yi"};//作位号或者每一节末尾输出(个节除外)
int main() {
	char str[12];
	scanf("%s", &str); //按字符串方式输入数字(不适用中间有空格的字符串输入)
	int len = strlen(str); //得字符串长度
	int left = 0, right = len - 1; //left 与 right 分别指向字符串首尾元素
	if (str[0] == '-') {
		printf("Fu");
		left++;//由于当前首位是“-”,所以跳过负号,始终让left指向数字首位
	}
//	每四个数字为一节,下面这个while循环是得到第一个节
	while (left + 4 <= right) {
		right -= 4;
	}
//此时right指向第一节的末位,left指向第一节的首位(如果第一节只有一位,那么他们指向相同的位置)

	while (left < len) { //循环每次处理字符串的一节(4位或小于4位)
		bool flag = false; //表示输出left小标对应数字前,没有累积的0
		bool Print = false;//表示该节没有输出过其中的位(一节中有4位或小于4位)
        //下面这个while循环是为了遍历当前节的每一位
		while (left <= right) { 
            //如果当前位为0,需要left > 0 是 针对083278这种以0开头的字符串,避免读入无效0
			if (str[left] == '0' && left > 0) {
				flag = true;//令标记为true
			} else {//如果当前位不为0
				if (flag == true) {//如果存在累积的0
					printf(" ling");//输出额外发音0
					flag = false;
				}
				if (left > 0) printf(" ");//只要不是首位(包括负号),后面的每一位前都要输出空格
				printf("%s", numb[str[left] - '0']);//输出当前数字
				Print = true;//该节至少有一位被输出
				if (left != right) {//说明当前节的数字还没有读完,要输出该位对应的位号,即某节中除了个位外,都需要输出十百千
					printf(" %s", post[right - left]);
				}
				
			}//上面对数字的输出,以及对数字对应位号输出的代码写在 else{} 里是处理100002828这种有连续多个0的情况,而我们只用读一个0,不然在输出当前数字那里就会输出很多个0
			left++;//left右移一位
		}
		//退出内层循环说明第一节的每一位已经处理完毕
		//现在输出该节末尾 万或者亿(个节不输出)
		if (Print && right != len - 1) {//个位(此时是最后一节,即个节)不输出
			printf(" %s", post[(len - right) / 4 + 3]);
		}
		right += 4;//right右移动四位,移到到下一节的末尾,重复进行上述操作
	}
	return 0;

}

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值