C++实现string类型的大数相加(带小数)

近日,做了一道阿里给的大数相加的编程题。题目大意如下:

输入两个string类型的数,如12.223  11,判断输入字符串是否合法。合法则输出true以及相加结果(true 23.223),非法则输出false """"。

期间几经修改,在判断合法方面排除了如.212以及122.这种错误(出现除数字以及.以外的错误亦已排除)。

主要的思路是将小数与整数部分进行分离,分别相加。由于小数部分可能想整数部分进位,需要进行进位判断。

完整代码如下:

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

string max_i,min_i;
bool carry_dem = false;									//判断小数是否需要向整数进位 

void count_int(string s1,string s2)						//计算整数部分的和
{
	max_i = s1;min_i = s2;
	if(s2.size()>s1.size())
	{
		max_i = s2;										//取长度大的数为max
		min_i = s1;
	}

	if(carry_dem)										//完成进位
		max_i[max_i.size() -1] ++;

	for(int i = min_i.size()-1,j = max_i.size()-1; i>=0;i--,j--)		//模拟整数加的过程
	{
		max_i[j] += min_i[i] -‘0‘;										//选择将结果保存在max变量中 

		if(max_i[j] > ‘9‘)
		{
			if(j > 0)
			{
				max_i[j - 1] ++;
				max_i[j] -= 10;
			}
			else
			{
				max_i = "1" + max_i;
				max_i[j] -= 10;
			}
		}
	}

}

string max_d,min_d;
void count_dem(string s1,string s2)					//对小数部分进行相加
{
	max_d = s1;min_d = s2;
	if(s2.size()>s1.size())
	{
		max_d = s2;
		min_d = s1;
	}

	for(int i=min_d.size()-1;i>=0;i--)
	{
		max_d[i] += min_d[i] -‘0‘;
		if(max_d[i] > ‘9‘)
		{
			if(i > 0)
			{
				max_d[i - 1] ++;
				max_d[i] -= 10;
			}
			else
			{
				carry_dem = true;					//设置进位标志
				max_d[i] -= 10;
			}
		}
	}

}

int main(){
	string s1,s2;
	cin>>s1>>s2;

	int i,j,k;

	bool legal = true;
	for(i = 0; i< s1.size();i++)					//完成字符串是否合法的判断
	{
		if(((s1[i]<‘0‘||s1[i]>‘9‘)&&(s1[i] != ‘.‘))||(s1[s1.size()-1] == ‘.‘)||(s1[0] == ‘.‘))
			legal = false;
	}
	for(i = 0; i< s2.size();i++)
	{
		if(((s2[i]<‘0‘||s2[i]>‘9‘)&&(s2[i] != ‘.‘))||(s2[s2.size()-1] == ‘.‘)||(s2[0] == ‘.‘))
			legal = false;
	}

	string integer_1,integer_2;						//取出字符串的整数部分
	string demical_1,demical_2;						//取出字符串的小数部分 

	if(!legal)
		cout<<"false "<<"\"\"\"\"";
	else
	{
		bool wi_dem1 = false,wi_dem2 = false;		//判断是否带小数
		int pos_s1 = 0,pos_s2 = 0;

		for(i = 0; i< s1.size();i++)
			if(s1[i] == ‘.‘)
			{
				wi_dem1 = true;
			}

		for(i = 0; i< s2.size();i++)
			if(s2[i] == ‘.‘)
			{
				wi_dem2 = true;
			}

		if((!wi_dem1)&&(!wi_dem2))					//两个数均不带小数部分
		{
			count_int(s1,s2);
			cout<<"true "<<max_i;
		}
		else
		{
			if(wi_dem1)								//第一个数带小数时分离整数、小数部分
			{
				pos_s1 = s1.find(".");
				integer_1 = s1.substr(0,pos_s1);
				demical_1 = s1.substr(pos_s1+1);
			}

			if(wi_dem2)								//第二个数带小数时分离整数、小数部分
			{
				pos_s2 = s2.find(".");
				integer_2 = s2.substr(0,pos_s2);
				demical_2 = s2.substr(pos_s2+1);
			}

			if(wi_dem2 && wi_dem1)					//均带小数
			{
				count_dem(demical_1,demical_2);
				count_int(integer_1,integer_2);

				cout<<"true "<<max_i<<"."<<max_d;
			}
			else if(!wi_dem2 && wi_dem1)
			{
				count_int(integer_1,s2);
				cout<<"true "<<max_i<<"."<<demical_1;
			}
			else
			{
				count_int(integer_2,s1);
				cout<<"true "<<max_i<<"."<<demical_2;
			}
		}
	}

	return 0;
}

  运行结果:

其中,部分代码仍可进行优化(博主比较懒...就没继续了),如判断是否带小数的判断以及后续的函数整合等。

原文地址:https://www.cnblogs.com/z1223/p/9591085.html

时间: 2024-08-06 03:05:26

C++实现string类型的大数相加(带小数)的相关文章

揭秘String类型背后的故事——带你领略汇编语言魅力

字符串或串(String)是由数字.字母.下划线组成的一串字符.一般记为 s="a1a2···an"(n>=0).它是编程语言中表示文本的数据类型.在程序设计中,字符串(string)为符号或数值的一个连续序列,如符号串(一串字符)或二进制数字串(一串二进制数字).String类型你一定不陌生,毕竟每一位coder都是从var str1 = "Hello World"过来的.但它真的就只是如此吗?听我娓娓道来.一.思考 在 Swift 开发使用字符串的过程中,

大数相加相乘

用乘法行列式多次相乘多次相加,时间复杂度为O(nm),n,m分别为两个数字长度. #include<stdio.h> #include<iostream> #include<string> #include<sstream> using namespace std; string a,b,ans,zero,product;///输入a,b,ans是最终答案,zero是乘法行列式补零用的,product暂时存储单位数乘积 int len1,len2,cha,m

C语言使用栈实现String类型的两个大数相加

要开始找工作了,记录下学习的关于数据结构的应用~~从栈开始~~ 栈和指针的应用~~~ 实现String类型的两个大数相加 主要思想是通过C语言的栈来实现,栈是后进先出的特点,因此很适合做这类计算.建立四个栈,分别按字符串字符先后顺序入栈大数的整数部分和小数部分,然后先计算小数部分的,由于小数部分是高位对齐,因此一直出栈最长小数栈的字符并进入小数结果的栈,小数位数对齐后,两个小数栈出栈进行相加.然后进行整数栈相加,由于整数部分是按低位对齐,因此直接出栈相加即可,将每位相加结果入结果整数栈.比如字符

HDU 1047 Integer Inquiry 大数相加 string解法

本题就是大数相加,题目都不用看了. 不过注意的就是HDU的肯爹输出,好几次presentation error了. 还有个特殊情况,就是会有空数据的输入case. #include <stdio.h> #include <vector> #include <string.h> #include <algorithm> #include <iostream> #include <string> #include <limits.h

高精度问题之大数相加(原来就是用字符串相加,模拟手算这么简单!)

解题心的: 就是基本的一对一模拟手算..借助c++的string 不用逆序运算了.很方便的补0.  最后处理下前导0的问题. #include <iostream> #include <string> using namespace std; // 实现大数相加 结果存放在num中 void bigIntergerAdd(string &num, string add) { int goBit = 0; // 存放进位 // 先交换下顺序 加数的位数要比较少 if (num

栈的应用—大数相加

package org.Stone6762.MStack.adopt;    import java.util.Scanner;    import org.Stone6762.MStack.imple.LinkStack;    /**  * @author_Stone6762  * @Description_大数相加  * */  public class BigAdd {        /**      * @Describe_将表示数字的字符串从高位到低位的形式压入栈_并去除其中的空格 

Java之大数相加

之前参加某公司笔试,机试题目是大数相加,两大数是字符串形式,求和. 当时讨巧用的是BigDecimal类,但是发迷糊了,以为b1.add(b2)后,和就加到b1上了,结果一直输出不对. 其实应该是这样: private static void add2Sum(String s1, String s2) { System.out.println("-----------"); BigDecimal b1 = new BigDecimal(s1); BigDecimal b2 = new

jstl foreach标签格式化date,string类型数据

本文要说jsp中date类型格式化和string类型分割处理 首先说date数据格式化 1.jsp中给date类型数据格式化首先需要引入 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> 如果后台带过来的数据是date类型,那就好办了,只要像下面这样用fmt标签就可以了,pattern定义时间的格式 <c:forEach items="${list}&quo

String类型,Function类型

1.String类型:  1)创建String对象:    var str=new String(s);    String(s);    参数:参数 s 是要存储在 String 对象中的值或转换成原始字符串的值.    返回值:当String()和运算符new一起作为构造函数使用时,它返回一个新创建的String对象,存放的是字符串s          当不用 new 运算符调用String()时,它只把 s 转换成原始的字符串,并返回转换后的值. 2)String对象属性:    leng