[C++] KY79 浮点数加法 北京大学复试上机题

题目链接

KY79 浮点数加法https://www.nowcoder.com/questionTerminal/ddec753f446e4ba4944e35378ba635c8

描述

求2个浮点数相加的和 题目中输入输出中出现浮点数都有如下的形式: P1P2...Pi.Q1Q2...Qj 对于整数部分,P1P2...Pi是一个非负整数 对于小数部分,Qj不等于0


输入描述:

对于对于每组案例,每组测试数据占2行,分别是两个加数。


输出描述:

每组案例是n行,每组测试数据有一行输出是相应的和。 输出保证一定是一个小数部分不为0的浮点数

示例1

输入
0.111111111111111111111111111111
0.111111111111111111111111111111

输出
0.222222222222222222222222222222

源代码

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

int main1() 
{
	string s = "abcdefg";
	cout << s.substr(1) << endl;

	string ss = "123456789";
	ss[0] = (char)('0'+5);
	cout << ss << endl;

	ss = '1' + ss;
	cout << ss << endl;
	return 0;
}

//习题4.4 浮点数加法
int main()
{
	string s1, s2;
	//每个测试输出包括多组案例的题目很常见,以后直接用while循环就好。除非明确说明只有一组输入
	//getline(cin, s1)是直接将一行输入读取并赋值给s1,这里用cin也可以。但是,对于一次输入中有多个空格的情况,如果直接用cin的话,每次只能读取一部分,不能满足题目要求。
	while (getline(cin, s1)) {
		getline(cin, s2);

		//分别得到两个字符串小数点的位置,方便后续获得两个字符串的整数和小数部分
		int pos1 = s1.find('.'); 
		int pos2 = s2.find('.');

		//分别得到两个字符串的整数部分,字符串的形式
		string ints1 = s1.substr(0, pos1);
		string ints2 = s2.substr(0, pos2);

		//分别得到两个字符串的整数部分,字符串的形式
		//由于截取是包括括号内位置所在索引,这里不需要小数点,所以从小数点后一位开始截取
		string floats1 = s1.substr(pos1+1); 
		string floats2 = s2.substr(pos2+1);

		//保证floats1的长度不大于floats2,后续只遍历floats1、更改floats2,方便许多
		if (floats1.length() > floats2.length()) { 
			swap(floats1, floats2);
		}

		int plus = 0; //记录每一位相加时的进位

		//从较短的那个小数部分的字符串的末位开始,对两个小数部分进行加法操作
		for (int i = floats1.size() - 1; i >= 0; i--) { 
			//对每一位字符代表的整数进行求和,整数字符得到整数用这种方法就可以了
			int sum = floats1[i] - '0' + floats2[i] - '0' + plus;
			//对于两个字符串在某一位相加和大于10的情况,要进行进位处理
			if (sum >= 10) {
				plus = 1;
				sum -= 10;
			}
			else {
				plus = 0;
			}
			//将处理过进位的结果赋值给floats2的相应位置。单个整数转字符串形式用这种方法就可以了
			floats2[i] = (char)(sum + '0');
		}
		
		//保证ints1的长度不大于ints2,后续只遍历ints1、更改ints2,方便许多
		if (ints1.length() > ints2.length()) { 
			swap(ints1, ints2);
		}
		//考虑到ints2的长度大于或等于ints1的长度,如果等于,其实没啥问题。
		//但是,如果ints2的长度大于ints1的长度,如ints2 = "12345"和ints1 = "678",要先右对齐再操作。如果要操作"678"的8,对应的是"12345"的5,但是二者在相应字符串中的索引不同,这里的gap就是用来对齐的
		int gap = ints2.length() - ints1.length();
		for (int i = ints1.size() - 1; i >= 0; i--) {
			//以下代码作用同对两个小数部分进行加法部分
			int sum = ints1[i] - '0' + ints2[i + gap] - '0' + plus; 
			if (sum >= 10) {
				plus = 1;
				sum -= 10;
			}
			else {
				plus = 0;
			}
			ints2[i + gap] = (char)(sum + '0');
		}

		//考虑ints2的长度大于ints1的长度,如ints2 = "12345"和ints1 = "678",678+345=1023,这里的进位1还需要进行处理
		//但是一次进位还可能引发其他的进位,如ints2 = "999345"和ints1 = "678",这里需要对于ints2比ints1长度多出来的那部分处理
		if (plus != 0) {
			for (int i = gap-1; i >= 0; i--) {
				//以下代码作用同对两个小数部分进行加法部分
				int sum = ints2[i] - '0' + plus;
				if (sum >= 10) {
					plus = 1;
					sum -= 10;
					ints2[i] = (char)(sum + '0');
				}
				//这里,如果发现sum<10,也就是不用进位了,其他的就不用处理了,直接退出循环
				//但是,先把已经得到的sum赋值给相应的位置
				else {
					ints2[i] = (char)(sum + '0');
					break;
				}
			}
		}
		//将相加得到的整数部分ints2、小数点、小数部分floats2输出即可
		cout << ints2 << "." << floats2 << endl;
	}

	return 0;
}

提交结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值