2018年5月份的在线编程笔试题第一题,投递岗位C++后台开发。
题目描述
两个大数使用string 表示,请实现一个函数,将他们相加。
注意:
1. 大数可能包含小数,比如:123.07+8796
2. 输入可能有误,请检查是否合法,不合法返回值为false
3. 大数不包含科学计数法。
思路
- 检查string是否合法;不合法返回“false”。
- 分离string,分成整数部分和小数部分。
- 对整数部分进行加法,先对齐补零。
- 对小数部分进行加法,先对齐补零。
- 负数情况如何处理?转化为大数减法。先判断哪个是作为被减数。
测试用例
空,+,-,.5,+345,-234;
code
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
// 正负数判断
bool isPositive(string number) // number合法情况下
{
if (number[0] == '-')
return false;
return true;
}
// 是否合法
bool isNumber(string number)// 空,+,-不合法
{
int len = number.size();
if (len <= 0)
return false;
int i = 0;
if ((number[i] == '+' || number[i] == '-') && len > 1)
{
i++;
}
while (number[i] != '.'&&i < len)
{
if (number[i]<'0' || number[i]>'9')
return false;
i++;
}
if (number[i] == '.')
{
i++;
while (i < len)
{
if (number[i]<'0' || number[i]>'9')
return false;
i++;
}
}
if (i == len)
return true;
return false;
}
// getting inter and decimal by '.'
bool gettingInterDecimal(string number, string &inter, string &decimal)
{
int position = number.find('.');
inter = number.substr(0, position);
if (position < number.size())
decimal = number.substr(position + 1, number.size());
return true;
}
string addAlign(string &add1, string &add2, int right, bool &carry) // right=1,mean 右对齐加;else 左对齐加
{
while (add2.size() < add1.size())
{
if (!right)
add2 += '0';
else
add2 = '0' + add2;
}
while (add1.size() < add2.size())
{
if (!right)
add1 += '0';
else
add1 = '0' + add1;
}
bool carryadd = 0;
string addsum = add1;
for (int i = add1.size()-1; i >= 0; i--)
{
addsum[i] = add1[i] + add2[i] + carryadd-'0';
if (addsum[i] > '9')
{
addsum[i] -= 10;
carryadd = 1;
}
else
carryadd = 0;
}
carry = carryadd;
return addsum;
}
bool cmpNumber(string inter1, string inter2, string decimal1, string decimal2)
{
if (inter1.size() != inter2.size())
return inter1.size() > inter2.size();
if (inter1.compare(inter2) != 0)
return inter1.compare(inter2)>=0;
return decimal1.compare(decimal2)>=0;
}
string subAlign(string &sub1, string &sub2, int right,bool &carry) // right=1,mean 右对齐加;else 左对齐加
{
while (sub1.size() < sub2.size()) // sub1 less means decimal
sub1 += '0';
while (sub2.size() < sub1.size())
{
if(!right)
sub2 += '0';
else
sub2 = '0'+sub2;
}
string sub=sub1;
bool carrysub = 0;
for (int i = sub2.size() - 1; i >= 0; i--)
{
sub[i] = sub1[i] - sub2[i] + '0'-carrysub;
if (sub[i] < '0')
{
carrysub = 1;
sub[i] += 10;
}
else
carrysub = 0;
}
carry = carrysub;
return sub;
}
string stringadd(string add1, string add2)
{
string sum;
bool isnumber = (isNumber(add1) && isNumber(add2));
if (!isnumber)
return "false";
bool add1sign = isPositive(add1);
bool add2sign = isPositive(add2);
if (add1[0] == '+' || add1[0] == '-')
add1.erase(0,1);
if (add2[0] == '+' || add2[0] == '-')
add2.erase(0,1);
string add1inter, add1de; // for integer and decimal
string add2inter, add2de;
gettingInterDecimal(add1, add1inter, add1de);
gettingInterDecimal(add2, add2inter, add2de);
if (add1sign == add2sign) // 同为正数和同为负数情况
{
bool carry1, carry2;
string decimalsum = addAlign(add1de, add2de, 0, carry2);
if (carry2)
{
if (add1inter.size() > 0)
add1inter[add1inter.size() - 1] += carry2;
else
add1inter = "1";
}
string intersum = addAlign(add1inter, add2inter, 1, carry1);
if (carry1)
intersum = '1' + intersum;
sum = intersum + "." + decimalsum;
if (!add1sign)
sum = '-' + sum;
}
else// 一个正数和一个负数情况,转化为减法,大数减小数
{
bool add1more = cmpNumber(add1inter, add2inter, add1de, add2de);
if (add1more)
{
bool carry;
string subdecimal = subAlign(add1de, add2de, 0,carry);
if(carry)
add1inter[add1inter.size() - 1] -= 1;
string subinter = subAlign(add1inter, add2inter,1, carry);
sum = subinter + "." + subdecimal;
if (!add1sign)
sum = "-" + sum;
}
else
{
bool carry;
string subdecimal = subAlign(add2de, add1de, 0,carry);
if(carry)
add2inter[add2inter.size() - 1] -= 1;
string subinter = subAlign(add2inter, add1inter, 1,carry);
sum = subinter + "." + subdecimal;
if (!add2sign)
sum = "-" + sum;
}
}
return sum;
}
void test()
{
string sum;
cout << stringadd(".89", "0.11") << endl;
cout << sum << endl;
cout << stringadd("123", "-456") << endl;
cout << sum << endl;
}
reference
另一种运算符重载思路 可参考
https://blog.csdn.net/to_be