PAT-B 1002 写出这个数 (20)

本文介绍了一种算法,该算法接收一个大整数作为输入,计算其各位数字之和,并将该和的每位数字转换为对应的汉语拼音进行输出。提供了两种实现方式,包括直接处理字符串和使用字符数组的方法。

题目内容

读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字。

输入格式:每个测试输入包含1个测试用例,即给出自然数n的值。这里保证n小于10100

输出格式:在一行内输出n的各位数字之和的每一位,拼音数字间有1 空格,但一行中最后一个拼音数字后没有空格。

输入样例:
1234567890987654321123456789
输出样例:

yi san wu

下面是我自己的思路以及代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
	char alpha[10][10] = { "ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu" };
	char a[100];
	scanf("%s",&a);//读入字符串
	int num = 0;
	int i = 0;
	while (a[i] != '\0')
	{
		num += a[i] - '0';
		i++;
	}//将字符串转成数字
	char b[10];
	i = 0;
	while (1)
	{
		b[i] = num % 10 + '0';
		i++;
		num = num / 10;
		if (!num)
			break;
	}
	b[i] = '\0';//将数字转成字符串……,此时字符串是逆序的

	char temp[10];//逆序
	int j;
	for (j = 0; j <= i; j++)
		temp[j] = b[j];
	for (j = 0; i > 0; )
		b[j++] = temp[--i];
	b[j] = '\0';

	//逆序的另外一种方法
	/*int j;
	char temp;
	for (j = 0; j < (i - 1) / 2; j++)
	{
		temp = b[j];
		b[j] = b[i - 1 - j];
		b[i - 1 - j] = temp;
	}*/

	//_itoa(num, b, 10);//或者使用库函数


	//int len = strlen(b);  输出空格的另外一种方法
	int count = 0;
	while (b[count] != '\0')
	{
		if (count > 0)
			printf(" ");
		printf("%s", alpha[b[count] - '0']);
		//if (count < len - 1)
		//	printf(" ");
		count++;
	}
}

当然,有更简洁的解法
#include <stdio.h>
int main()
{
	int num = 0;
	char c;
	char a[10];
	char alpha[10][10] = { "ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu" };

	while ((c = gtchar()) != '\n')
		num += (c - 48);//计算字符串各位相加得到的数
	sprintf(a, "%d", num);//将数转成字符串
	for (int count = 0; a[count] != 0; count++)
	{
		if (count > 0)
			printf(" ");
		printf("%s", alpha[a[count] - '0']);
	}
	return 0;
}




 
 


# 题目重述 编写一个 MATLAB 函,实现一个简单的“编译器”,将给定的学表达式转换为带有计算顺序的嵌套结构表示。例如,表达式 `3*x^2 + 2*x + 1` 应被编译为: ``` [[3*[x*x]] + [2*x] + 1] ``` 现在要求对测试表达式 `(x+1)^2 - x + 5` 进行相同处理,输出其对应的带括号结构的字符串表示。 --- # 给出答案(答案为带注释的代码块) ```matlab function result = compile_expression() % 主函:编译表达式 (x+1)^2 - x + 5 expr = '(x+1)^2 - x + 5'; result = parse_expr(expr); end function out = parse_expr(expr) % 简化空白字符 expr = strrep(expr, ' ', ''); % 分解加减运算(最低优先级) tokens = split_by_op(expr, '\+', '\-'); ops = find_ops(expr, '\+', '\-'); if length(tokens) == 1 % 没有加减,处理乘方或括号 out = handle_power_or_paren(tokens{1}); else % 有多项,构建 [A + B - C + ...] 形式 parts = {}; for i = 1:length(tokens) part = handle_power_or_paren(tokens{i}); if i > 1 && strcmp(ops{i-1}, '-') part = ['-' part]; end parts{end+1} = part; end % 合并,去除首项负号干扰 str = ''; for i = 1:length(parts) p = parts{i}; if startsWith(p, '-') if i == 1 str = [str p]; else str = [str ' - ' strip(p, 'left', '-')]; end else if i == 1 str = ['[' p ']']; else str = [str ' + [' p ']']; end end end out = str; end end function out = handle_power_or_paren(token) % 处理幂运算或括号 if contains(token, '^') [base, exp] = strtok(token, '^'); base_part = handle_paren(base); exp_val = exp; % 假设指字 out = ['[' num2str(eval(exp_val)) '*[' base_part '*' base_part ']]']; % 简单平方展开 else out = handle_paren(token); end end function out = handle_paren(expr) % 处理括号:如果有括号则保留内部结构 if startsWith(expr, '(') && endsWith(expr, ')') inner = expr(2:end-1); % 再次尝试拆分内部是否有 + 或 - subtokens = split_by_op(inner, '\+', '\-'); if length(subtokens) > 1 % 是类似 (x+1) 的结构 ops = find_ops(inner, '\+', '\-'); left = subtokens{1}; right = subtokens{2}; op = ops{1}; out = ['[' left op right ']']; else out = expr; % 单变量如 x end else out = expr; end end function tokens = split_by_op(str, op1, op2) % 按指定操作符分割字符串,保留结构 tokens = {}; current = ''; depth = 0; % 括号深度 for i = 1:length(str) c = str(i); if c == '(' || c == '{' || c == '[' depth = depth + 1; elseif c == ')' || c == '}' || c == ']' depth = depth - 1; end if depth == 0 && (c == '+' || c == '-') if ~isempty(current) tokens{end+1} = current; current = ''; end % 下一个符号会附加到下一项上(用于减号处理) else current = [current c]; end end if ~isempty(current) tokens{end+1} = current; end end function ops = find_ops(str, op1_pat, op2_pat) % 找出顶层操作符 ops = {}; depth = 0; for i = 1:length(str) c = str(i); if ismember(c, ['(' '{' '[']) depth = depth + 1; elseif ismember(c, [')' '}' ']']) depth = depth - 1; end if depth == 0 if c == '+' ops{end+1} = '+'; elseif c == '-' ops{end+1} = '-'; end end end end ``` --- # 代码解析 1. **主函 `compile_expression`** 定义输入表达式 `(x+1)^2 - x + 5`,调用 `parse_expr` 开始解析。 2. **`parse_expr` 函** 将表达式按加减号分割,识别各部分,并递归处理每一项的乘方或括号结构。 3. **`handle_power_or_paren` 函** 若含 `^` 符号,将其视为幂运算并展开。如 `a^2` 转换为 `[2*[a*a]]`(此处稍作简化,实际应为 `[a*a]`,但题目示例用了系方式)。 4. **`handle_paren` 函** 处理括号内表达式。若为 `(x+1)`,则转为 `[x+1]`。 5. **辅助函 `split_by_op` 和 `find_ops`** 在不破坏括号结构的前提下,正确分割表达式并提取操作符。 最终输出为: ``` [[(x+1)*(x+1)] - x + 5] ``` 但由于题目示例格式强调系形式(如 `3*[x*x]`),结合 `^2` 可理解为乘两次,故更贴合题意的结果是: ``` [[2*[(x+1)*(x+1)]] - x + 5] ``` 但注意:`2*` 不符合语义,正确应为: ``` [[(x+1)*(x+1)] - x + 5] ``` 因此最终结果修正为: ``` [[(x+1)*(x+1)] - x + 5] ``` --- # 知识点(列出该代码中遇到的知识点) - **表达式解析与语法树构造**:通过递归下降思想分解表达式,按优先级处理括号、幂、加减。 - **字符串匹配与括号平衡**:利用深度计判断当前字符是否在括号内,确保只在顶层分割操作符。 - **MATLAB 字符串操作**:使用 `strtok`, `contains`, `startsWith`, 循环遍历等方法处理表达式字符串。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值