【算法笔记】之高精度算法

133 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

【算法笔记】之高精度算法

目录

高精度加法

高精度减法

高精度乘法

高精度除法

如果参与计算的数过大,比如1000位数进行相乘,普通的方法很难满足,这就要涉及高精度算法了,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘,开方等运算。

高精度加法 给定两个正整数(不含前导 00),计算它们的和。

输入格式

共两行,每行包含一个整数。

输出格式

共一行,包含所求的和。

数据范围

1≤整数长度≤1000001≤整数长度≤100000

输入样例:

12 23 输出样例:

35 #include #include using namespace std; vectoradd(vector&A,vector&B){ if(A.size()<B.size()) return add(B,A); vectorc; int t = 0; for(int i =0;i<A.size();i++){ t+=A[i];//t与每一个数的相应位数相加 if(i<B.size()) t += B[i]; c.push_back(t%10);//把余数输出 t /= 10;//商保留,下一位进位要加上这个数

} if(t) c.push_back(t); return c;

} int main(){ string a,b; vectorA,B; cin>>a>>b;

for(int i = a.size()-1;i>=0;i--)A.push_back(a[i]-'0');//与ASCII码有关,两个字符相减才是这个值
for(int i = b.size()-1;i>=0;i--)B.push_back(b[i]-'0');
auto c = add(A,B);//auto会自动判断数据类型
for(int i = c.size()-1;i>=0;i--)cout<<c[i];
    cout<<endl;//换行
return 0;

}

高精度减法 给定两个正整数(不含前导 00),计算它们的差,计算结果可能为负数。

输入格式

共两行,每行包含一个整数。

输出格式

共一行,包含所求的差。

数据范围

1≤整数长度≤1051≤整数长度≤105

输入样例:

32 11 输出样例:

21 #include #include

using namespace std;

bool cmp(vector &A, vector &B) { if (A.size() != B.size()) return A.size() > B.size();//位数不同

for (int i = A.size() - 1; i >= 0; i -- )//位数相同再进行的判断
    if (A[i] != B[i])
        return A[i] > B[i];

return true;

}//先判断两个数的大小

vector sub(vector &A, vector &B) { vector C; for (int i = 0, t = 0; i < A.size(); i ++ ) { t = A[i] - t; if (i < B.size()) t -= B[i]; C.push_back((t + 10) % 10); if (t < 0) t = 1; else t = 0; }

while (C.size() > 1 && C.back() == 0) C.pop_back();//去除前导0
return C;

}

int main() { string a, b; vector A, B; cin >> a >> b; for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0'); for (int i = b.size() - 1; i >= 0; i -- ) B.push_back(b[i] - '0');

vector<int> C;

if (cmp(A, B)) C = sub(A, B);//判断两数的大小
else C = sub(B, A), cout << '-';小的数减一个大的数前要加负号

for (int i = C.size() - 1; i >= 0; i -- ) cout << C[i];//逆序输出
cout << endl;

return 0;

}

高精度乘法 给定两个非负整数(不含前导 00) AA 和 BB,请你计算 A×BA×B 的值。

输入格式

共两行,第一行包含整数 AA,第二行包含整数 BB。

输出格式

共一行,包含 A×BA×B 的值。

数据范围

1≤A的长度≤1000001≤A的长度≤100000, 0≤B≤100000≤B≤10000

输入样例:

2 3 输出样例:

6 #include #include using namespace std; vectormul(vector&A,int b){ vectorc; int t = 0; for(int i = 0;i<A.size()||t;i++){ if(i<A.size()) t += A[i]*b; c.push_back(t%10); t /= 10; } while(c.size()>1&&c.back()==0)c.pop_back();//去除前导0 return c; } int main(){ string a; int b; cin>>a>>b; vectorA; for(int i = a.size()-1;i>=0;i--) A.push_back(a[i] - '0');

auto c = mul(A,b);
for(int i = c.size()-1;i>=0;i--) cout<<c[i];
cout<<endl;
return 0;

}

高精度除法 给定两个非负整数(不含前导 00) A,BA,B,请你计算 A/BA/B 的商和余数。

输入格式

共两行,第一行包含整数 AA,第二行包含整数 BB。

输出格式

共两行,第一行输出所求的商,第二行输出所求余数。

数据范围

1≤A的长度≤1000001≤A的长度≤100000, 1≤B≤100001≤B≤10000, BB 一定不为 00

输入样例:

7 2 输出样例:

3 1 #include #include #include using namespace std; vectordiv(vector&A,int b,int&t){ vectorc; t = 0; for(int i = A.size ()-1;i>=0;i-- ){ t = t*10 + A[i]; c.push_back(t/b); t = t%b; } reverse(c.begin(),c.end());//再翻转一次就是结果 while(c.back()==0&&c.size()>1) c.pop_back();//去除前导0 return c; } int main(){ string a; int b; cin>>a>>b; vectorA; for(int i = a.size()-1;i>=0;i--)A.push_back(a[i] - '0'); int t; auto c = div (A,b,t); for(int i = c.size()-1;i>=0;i--)cout<<c[i]; cout<<endl<<t<<endl;

}