5.6华为机试第二题C++复盘

【表达式计算】:

给定一个字符串形式的表达式,保证每个字符串表达式中仅包含加(+)这1种运算符,计算并输出表达式结果。

要注意的是,+号两边的数据仅可能包含数字字符、小数点字符与特殊字符,特殊字符包括!@#,这些特殊字符的加法运算有特别的规则:

!+!=0

!+@=13

!+#=4

@+@=7

@+#=20

#+#=5

注意:

1.保证每个表达式仅包含—个运算符

2.保证表达式一定可运算且有数据结果

3.保证运算符两边数据有效(不会出现包含两个小数点之类的无效数据)

4.表达式内不存在空格

5特殊字符的加法运算符合交换律

6.如果表达式中包含特殊字符,则运算中不会出现数字与特殊字符的加法运算

7.表达式两边的数据均不以0开头,比如不会出现这样的表达式:0250+0110

【解答要求】:

时间限制:C/C++1000ms,其他语言:2000ms

内存限制:C/C++ 256MB,其他语言:512MB

【输入】:

第一行:代表字符串长度(长度在[1,100]之间)

第二行:代表一个字符串表达式

【输出】:

输出一行,输出表达式结果

注意:

注意:小数最后位如果为0则省略,如结果250.010则输出250.01,结果250.0则省略为250;同时,如果计算结果为”0250”,也需以最简化形式“250"输出。

【样例】1

输入:15

123.45#1+126.53@

输出:250.0001

解释:#+@=20,即进2位,表达式结果为250.0001

竖式运算如下:

123.45#1

126.53@

-------------

250.0001

#include <iostream>
#include <string>
using namespace std;

int special_add(char s1, char s2) {
	if (s1 == '!') {
		if (s2 == '!') return 0;
		else if (s2 == '@') return 13;
		else if (s2 == '#') return 4;
	} else if (s1 == '@') {
		if (s2 == '@') return 7;
		else if (s2 == '#') return 20;
		else if (s2 == '!') return 13;
	} else if (s1 == '#') {
		if (s2 == '#') return 5;
		else if (s2 == '@') return 20;
		else if (s2 == '!') return 4;
	}
	return 0;
}

int main() {
	int len;
	string exp;
	cin >> len >> exp;
	int pos = exp.find("+");  // 查找加号位置
	string op1 = exp.substr(0, pos);  // 第一个操作数
	string op2 = exp.substr(pos + 1);  // 第二个操作数
	string op11, op12, op21, op22;
	int pos1 = op1.find(".");
	if (pos1 != -1) {
		op11 = op1.substr(0, pos1);
		op12 = op1.substr(pos1 + 1);
	} else {
		op11 = op1;
		op12 = "0";
	}
	int pos2 = op2.find(".");
	if (pos2 != -1) {
		op21 = op2.substr(0, pos2);
		op22 = op2.substr(pos2 + 1);
	} else {
		op21 = op2; 
		op22 = "0"; 
	}
	if (op11.size() < op21.size()) swap(op11, op21);
	if (op12.size() < op22.size()) swap(op12, op22);
	int addition_carry = 0;
	for (int i = op12.size() - 1; i > -1; i--) {
		if (i > op22.size() - 1) {
			if (op12[i] == '!' || op12[i] == '@' || op12[i] == '#') {
				op12[i] = '0';
			}
		} else {
			if (op12[i] == '!' || op12[i] == '@' || op12[i] == '#') {
				int special_res = special_add(op12[i], op22[i]) + addition_carry;
				op12[i] = special_res % 10 + '0';
				addition_carry = special_res / 10;
			} else {
				int n1 = int(op12[i]) - int('0');
				int n2 = int(op22[i]) - int('0');
				op12[i] = (n1 + n2 + addition_carry) % 10 + '0';
				addition_carry = (n1 + n2 + addition_carry) / 10;
			}
		}
	}
	string s(op11.size() - op21.size(), '0');
	op21 = s + op21;

	for (int i = op11.size() - 1; i > -1; i--) {
		if (op11[i] == '!' || op11[i] == '@' || op11[i] == '#') {
			int special_res = special_add(op11[i], op21[i]) + addition_carry;
			op11[i] = special_res % 10 + '0';
			addition_carry = special_res / 10;
		} else {
			int n1 = int(op11[i]) - int('0');
			int n2 = int(op21[i]) - int('0');
			op11[i] = (n1 + n2 + addition_carry) % 10 + '0';
			addition_carry = (n1 + n2 + addition_carry) / 10;
		}
	}
	
	if (addition_carry > 0) {
		char first_num = addition_carry + '0';
		op11.insert(0, 1, first_num);
	}
	//去掉首0
	int i = 0;
	for (i; i < op11.size(); i++)
		if (op11[i] != '0') 
			break;
	if (i >= 0 && i < op11.size()) op11 = op11.substr(i); 
	if (i >= op11.size()) op11 = "0";
	//去掉尾0
	i = op12.size() - 1;
	for (i; i > -1; i--)
		if (op12[i] != '0')
			break;
	string res = op11 + "." + op12.substr(0, i + 1);
	cout << res << endl;
	return 0;
}

全部评论
这,感觉比我的第二题简单,考试时脑抽没想到用递归,考完交卷才想起来可以用,G
点赞 回复 分享
发布于 2023-05-07 16:19 江苏
华为机试一般都考什么?
点赞 回复 分享
发布于 2023-05-07 20:33 天津
请问你这个代码通过率咋样呀?
点赞 回复 分享
发布于 2023-05-07 23:48 江苏

相关推荐

投了好多家都没约到面试,是不是简历写的有问题,求助各位牛友帮忙看看简历
叶墨沫:教育经历时间直接一步到位写毕业时间,写清楚自己那一届应届生,不然面试官还好数数手指你是25还是26
点赞 评论 收藏
分享
08-14 11:09
已编辑
南阳理工学院 Java
点赞 评论 收藏
分享
forzht:xd,这个不是24届的问题。别怪我说话不太好听,你的实习经历没任何意义啊,全是人家给你介绍啥技术,你做了啥啊剩下就没有啥了,这25届也难,现在不是原来了
点赞 评论 收藏
分享
2 16 评论
分享
牛客网
牛客企业服务