大數運算-模擬
阿新 • • 發佈:2018-11-06
對於大數加法,減法和乘法都可以用模擬的方法來解決,對於除法(一直做減法),要使用加法和減法。
大數乘法
/*
Leetcode 43. Multiply Strings
Given two numbers represented as strings, return multiplication of the numbers as a string.
Note:
The numbers can be arbitrarily large and are non-negative.
Converting the input string to integer is NOT allowed.
You should NOT use internal library such as BigInteger.
解題思路:模擬手算。第i位乘以第j位得到的是(i+j)位的數
*/
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
string multiply(string num1, string num2)
{
//先要反轉,把最低位放在0的位置
reverse(num1.begin(), num1.end());
reverse(num2.begin(), num2.end());
int tmp = 0;
string s(num1.length() + num2.length(), '0');
for (size_t i = 0; i < num1.length(); ++i)
{
for (size_t j = 0; j < num2.length(); ++j)
{
tmp = (num1[i] - '0') * (num2[j] - '0'); //tmp為i位*j位
//把進位加到i+j+1位上
s[i + j + 1 ] = s[i + j + 1] - '0' + (s[i + j] - '0' + tmp) / 10 + '0';
//非進位的部分留在i+j位上
s[i + j] = (s[i + j] - '0' + tmp) % 10 + '0';
}
}
//處理完成後反轉
reverse(s.begin(), s.end());
//去掉前面的0
auto pos = s.find_first_not_of('0');
if (pos == string::npos) //為0的情況
return "0";
else
return s.substr(pos);
}
};
void TEST()
{
Solution sol;
string s1 = "123";
string s2 = "234";
cout << sol.multiply(s1, s2) << endl;
}
int main()
{
TEST();
return 0;
}
大數除法(包含加法和減法)
/*
OpenJudge2737 大數除法
輸入兩個數,第一個被除數,第二個為除數,不超過100位
輸出:商的整數部分
*/
#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
using namespace std;
string sub(string s1, string s2)
{
int flag = 0;
if (s1.length() < s2.length() || ((s1.length() == s2.length()) && s1 < s2))
{
flag = 1;
string tmp = s1;
s1 = s2;
s2 = s1;
}
int i, j;
for (i = s1.length() - 1, j = s2.length() - 1; i >= 0; i--, j--)
{
s1[i] = char(s1[i] - (j >= 0 ? s2[j]-'0' : 0));
if (s1[i] < '0')
{
--s1[i - 1];
s1[i] += 10;
}
}
for (i = 0; i < s1.length(); ++i)
{
if (s1[i] != '0') break;
}
if (i == s1.length()) i = s1.length() - 1;
s1 = s1.substr(i);
if (flag) s1 = "-" + s1;
return s1;
}
string add(string s1, string s2)
{
if (s1.length() < s2.length())
{
string tmp = s1;
s1 = s2;
s2 = tmp;
}
int i, j;
for (i = s1.length() - 1, j = s2.length() - 1; i >= 0; --i,--j)
{
s1[i] = char(s1[i] + (j >= 0 ? s2[j] - '0' : 0));
if (s1[i] - '0' >= 10)
{
s1[i] = (s1[i] - '0') % 10 + '0';
if (i)
s1[i - 1]++;
else
s1 = "1" + s1;
}
}
return s1;
}
string div(string s1, string s2)
{
string res = "0";
if (s1.size() < s2.size() || (s1.size() == s2.size() && s1 < s2))
{
return "0";
}
int i;
int subLen = s1.size() - s2.size();
for (i = subLen; i >= 0; --i)
{
string s3(i, '0');
string s4 = s2 + s3;
//這裡做減法,直到s1比s4小
do
{
string tmp = sub(s1, s4);
if (tmp[0] == '-') break; //不夠除
else
{
s1 = tmp;
res = add(res, ("1" + s3));//根據s3的位數來確定加的數
}
} while (1);
}
return res;
}
//順便把乘法寫了
string mul(string s1, string s2)
{
reverse(s1.begin(), s1.end());
reverse(s2.begin(), s2.end());
int tmp = 0;
string s(s1.size() + s2.size(), '0');
for (int i = 0; i < s1.size(); ++i)
{
for (int j = 0; j < s2.size(); ++j)
{
tmp = (s1[i] - '0')*(s2[j] - '0');
//進位
s[i + j + 1] = s[i + j + 1] + (s[i + j] - '0' + tmp) / 10;
//非進位
s[i + j] = (s[i + j] - '0' + tmp) % 10 + '0';
}
}
reverse(s.begin(), s.end());
int pos = s.find_first_not_of('0');
if (pos == -1)
return "0";
else
return s.substr(pos);
}
int main()
{
string s1, s2;
cin >> s1 >> s2;
cout << div(s1, s2) << endl;
return 0;
}