前言:哎,做题好难o(╥﹏╥)o,有时候想不到,而有时候则是想到了却没办法理清思路,转化为代码。有必要反思了┓(;´_`)┏,是否是做的太少了,或是自己的基础欠缺。
大学总是有些迷茫~
大数相加:
就简单的加法而言,我觉得口算也是很快了,生活完全够用,但一旦上了几十几百或更多,并且不是整十整百的,嗯~实在是难为我,有时候在家父母有时也揪着不放:“都上大学得到人了,口算这么差?” 我又不是人形计算器!!况且,就大学生而言,平均来说,是不是有些高估了?
(= ̄ω ̄=)喵了个咪
回归正题,大数相加,嗯,很大很大的数,有可能会溢出的那种┗( ▔, ▔ )┛。使用 return x * y; 这种明显不行了,换种思路,就到了今天我要说的了,对!就是将其用string解决。
但到底怎么解决呢?有些头疼呢~~
有兴趣的可以先思考思考,再往下面看。
思路:想想我们平常是怎么计算的?
1 2 3
+ 2 3 4
-------------
3 5 7遇到进位:
4 5 6
+ 7 8 9
-------------
15
向前进1
1 5
-------------
14 5
-------------
1<-4 5
--------------
1<-12 4 5
--------------
1 2 4 5小学就学过吧,想不到最年幼时学的东西竟可以陪伴我这么久,并且还是最实用的
!!!∑(゚Д゚ノ)ノ
不妨,我们就来模拟这个过程:将大数变为一位一位的小数相加
首先,这好像跟我们的string的顺序相反哎!!!怎么办?难道就这么放弃了吗?不,不如就反着算!最后再倒过来就行了。
那么,首先的把字符转化为数字,好说好说:x - '0' 即可,然后再相加,但得标记一下进位,于是:
//数一:num1 数二: num2
int end1 = num1.size() - 1;
int end2 = num2.size() - 1;
int next = 0;
//一个简单的三目操作符完成字符与数的转换
int n1 = end1 >= 0 ? num1[end1] - '0' : 0;
int n2 = end2 >= 0 ? num2[end2] - '0' : 0;
int x = n1 + n2 + next;
next = x / 10;
x %= 10;
//最后,next就是进位了, x就是最低位相加的结果了
//找个字符串先存起来再说
string retnum;
retnum += (x + '0');
数字可能有很多位,用循环即可,每一次加在retnum后面就行了
string retnum;
int end1 = num1.size() - 1;
int end2 = num2.size() - 1;
int next = 0;
while (end1 >= 0 || end2 >= 0)
{
int n1 = end1 >= 0 ? num1[end1--] - '0' : 0;
int n2 = end2 >= 0 ? num2[end2--] - '0' : 0;
int x = n1 + n2 + next;
next = x / 10;
x %= 10;
//retnum.push_back(x + '0');
retnum += ('0' + x);
}
当然,最高位相加也是有可能进位的!
if (next != 0)
{
retnum += '1';
}
最后反转一下
reverse(retnum.begin(), retnum.end());
欧耶!终于完成了!
写完代码总是让我有很强的满足含感,不知道各位如何。
以下是完整代码,有需要的小伙伴可以自取:
class Solution {
public:
string addStrings(string num1, string num2)
{
string retnum;
int end1 = num1.size() - 1;
int end2 = num2.size() - 1;
int next = 0;
while (end1 >= 0 || end2 >= 0)
{
int n1 = end1 >= 0 ? num1[end1--] - '0' : 0;
int n2 = end2 >= 0 ? num2[end2--] - '0' : 0;
int x = n1 + n2 + next;
next = x / 10;
x %= 10;
//retnum.push_back(x + '0');
retnum += ('0' + x);
}
if (next != 0)
{
retnum += '1';
}
reverse(retnum.begin(), retnum.end());
return retnum;
}
};
做完总得试一试呗:
int main()
{
Solution S;
string ret = S.addStrings("1234", "3457800000");
cout << ret << endl;
string ret1 = S.addStrings("1234452523", "345780000023");
cout << ret1 << endl;
return 0;
}
//3457801234
//347014452546
//2460
//D:\编程\text_c\greate_number_add\x64\Debug\greate_number_add.exe (进程 2344)已退出,代码为 //0 (0x0)。
//按任意键关闭此窗口. . .
大数相乘:
做完了大数相加,额,来个大数相乘练练手!(信心满满)
..............................
啊,貌似有些难度!
相乘的话,就不是简单的想同位相加(乘)了,每一位都得乘,这得很多位啊,数越大越多,脑子好像有些不够用了⊙(・◇・)?!!
别急,来让我们细细思考:平时我们在草稿纸上是怎么做的?
数一与数二相乘,数二的每一位都与数一的每一位相乘,并且随着数二从个位到百位千位......相乘所得的结果也在变大,即“天生进位!”(我命名的)。
数二的所有位与数一相乘后,最后相加得结果。
大数相加在上面我们已经完成了,接下来,只需要实现数二的每一位都与数一的每一位相乘,并且“天生进位”就可以了。
string multiply(string num1, string num2) {
if (num1 == "0" || num2 == "0")
return"0";
int end1 = num1.size() - 1;
int end2 = num2.size() - 1;
//定义一个字符串,用于记录每次相加的结果,最后用于返回
string retnum("0");
for (int i = end2; i >= 0; i--)
{
//标记进位
int next = 0;
string cur;
//char转int
int x = num2[i] - '0';
for (int j = end2; j > i; j--)
{
//这一步就是用于数二数位的变大而准备的“天生进位”
cur.push_back('0');
}
for (int j = end1; j >= 0; j--)
{
//这里代码与大数相加很相似,只不过加换做了乘
int y = num1[j] - '0';
int n = x * y + next;
next = n / 10;
n %= 10;
cur.push_back('0' + n);
}
//注意,由于是乘法,进位的数字有可能较大
while (next != 0)
{
cur.push_back(next % 10 + '0');
next /= 10;
}
//反转
reverse(cur.begin(), cur.end());
//在这numadd就是大数相加了
retnum = numadd(retnum, cur);
}
return retnum;
}
有大数相加的经验,我就不一一细讲了,相信你们举一反三都是手拿把掐!!
这里是完整代码,有需自取:
//大数相乘
class Solution1 {
public:
string multiply(string num1, string num2) {
if (num1 == "0" || num2 == "0")
return"0";
int end1 = num1.size() - 1;
int end2 = num2.size() - 1;
string retnum("0");
for (int i = end2; i >= 0; i--)
{
int next = 0;
string cur;
int x = num2[i] - '0';
for (int j = end2; j > i; j--)
{
cur.push_back('0');
}
for (int j = end1; j >= 0; j--)
{
int y = num1[j] - '0';
int n = x * y + next;
next = n / 10;
n %= 10;
cur.push_back('0' + n);
}
while (next != 0)
{
cur.push_back(next % 10 + '0');
next /= 10;
}
reverse(cur.begin(), cur.end());
retnum = numadd(retnum, cur);
}
return retnum;
}
string numadd(string num1, string num2)
{
string retnum;
int end1 = num1.size() - 1;
int end2 = num2.size() - 1;
int next = 0;
while (end1 >= 0 || end2 >= 0)
{
int n1 = end1 >= 0 ? num1[end1--] - '0' : 0;
int n2 = end2 >= 0 ? num2[end2--] - '0' : 0;
int x = n1 + n2 + next;
next = x / 10;
x %= 10;
//retnum.push_back(x + '0');
retnum += ('0' + x);
}
if (next != 0)
{
retnum += '1';
}
reverse(retnum.begin(), retnum.end());
return retnum;
}
};
好了,本次分享就结束了,谢谢观看!!
但学习之路永无止境,即使是跑一会歇一会,我也会向前进!!