大整数四则运算------(c++ 实现 乘法没有用傅里叶变换)
/* 优点:
1 支持负整数的运算
2 良好的输出形式 没有前导零
3 支持cin直接输入 支持cout直接输出
4 支持整数的直接赋值 big_int x=100;
缺点:
1 封装不好 基本都是友元函数操作
2 速度慢 乘法没有使用FFT 除法采用二分法
使用STL string储存数据也造成速度不是很快
3 待解决的问题 不能直接输出 cout<<a-b
*/ #include <iostream>
#include <algorithm>
#include <stack>
using namespace std;
void change (string &s) {
string tmp="";
int i;
for (i=;i<s.size();i++)
if (s[i]!='')
break;
if (i==s.size()) s="";
else {
for (;i<s.size();i++)
tmp+=s[i];
s=tmp;
}
}
class big_int
{
private :
bool flag;
string s;
public :
big_int (){ flag=; s=""; }
big_int (int x);
bool operator ==(const big_int& x) {
string tmp=x.s;
change (s);
change (tmp);
if (x.s==""&&s=="") return true;
return x.flag==flag&&s==tmp;
}
friend big_int operator+(const big_int& a, const big_int& b );
friend big_int operator-(const big_int& a, const big_int& b );
friend big_int operator*(const big_int& a, const big_int& b);
friend big_int operator/(const big_int& a, const big_int& b);
friend big_int operator%(const big_int& a, const big_int& b);
friend ostream& operator<<(ostream& out,big_int& x) {
if (!x.flag&&x.s!="") cout<<"-";
change (x.s);
cout<<x.s;
return out;
}
friend istream& operator>>(istream& in,big_int& x) {
string tmp;
cin>>tmp;
if (tmp[]=='-') {
x.flag=;
x.s=tmp.substr(,tmp.size()-);
}
else {
x.flag=;
x.s=tmp;
}
return in;
}
};
big_int:: big_int (int x) {
if (x<) flag=;
else flag=;
x=abs(x); s=""; string tmp="";
if (x==) s+=tmp;
while (x!=) {
tmp[]=''+x%;
s+=tmp;
x/=;
}
reverse(s.begin(),s.end());
}
string add(string s1,string s2) {
reverse(s1.begin(),s1.end());
reverse(s2.begin(),s2.end());
int len =max (s1.size(),s2.size());
int k=; int t1,t2;
string ans=""; string tmp="";
for (int i=;i<len;i++) {
t1=t2=;
if (i<s1.size()) t1=s1[i]-'';
if (i<s2.size()) t2=s2[i]-'';
int t=t1+t2+k;
tmp[]=''+t%; k=t/;
ans+=tmp;
}
if (k!=) {
tmp[]=''+k;
ans+=tmp;
}
reverse(ans.begin(),ans.end());
return ans;
}
string sub (string s1,string s2) {
reverse(s1.begin(),s1.end());
reverse(s2.begin(),s2.end());
int len =s1.size();
int t1,t2;
string ans=""; string tmp="";
for (int i=;i<len;i++) {
t1=s1[i]-''; t2=;
if (i<s2.size()) t2=s2[i]-'';
if (t1<t2) {
for (int j=i+;j<len;j++)
if (s1[j]-''==) s1[j]='';
else {
s1[j]--;
break;
}
t1+=;
}
tmp[]=t1-t2+'';
ans+=tmp;
}
reverse(ans.begin(),ans.end());
change(ans);
return ans;
}
bool m_cmp (string s1, string s2) {
change (s1);
change (s2);
if (s1.size()==s2.size()) {
for (int i=;i<s1.size();i++)
if (s1[i]!=s2[i])
return s1[i]>s2[i];
}
return s1.size()>s2.size();
}
string s_mul (string s,int x,int k) {
string ans=""; string tmp="";
for (int i=;i<=k;i++) ans+=tmp;
k=;
for (int i=;i<s.size();i++) {
int t=s[i]-'';
int p=t*x+k;
tmp[]=''+p%; ans+=tmp;
k=p/;
}
if (k) {
tmp[]=''+k;
ans+=tmp;
}
reverse(ans.begin(),ans.end());
change(ans);
return ans;
}
string mul (string s1,string s2) {
reverse(s1.begin(),s1.end());
reverse(s2.begin(),s2.end());
string ans="";
for (int i=;i<s2.size();i++) {
int x=s2[i]-'';
string tmp=s_mul (s1,x,i);
ans=add(ans,tmp);
//cout<<ans<<endl;
}
return ans;
}
big_int operator+(const big_int& a, const big_int& b ) {
big_int c;
int t=a.flag^b.flag;
if (t==) {
c.s=add (a.s,b.s);
c.flag=a.flag;
}
else {
if (m_cmp(a.s,b.s)) {
c.flag=a.flag;
c.s=sub (a.s,b.s);
}
else {
c.flag=b.flag;
c.s=sub (b.s,a.s);
}
}
return c;
}
big_int operator-(const big_int& a, const big_int& b ) {
big_int c=b;
c.flag=!b.flag;
return a+c;
}
big_int operator*(const big_int& a, const big_int& b) {
big_int c;
int t=a.flag^b.flag;
if (t) c.flag=;
if (m_cmp(a.s,b.s)) c.s=mul (a.s,b.s);
else c.s=mul (b.s,a.s);
return c;
}
big_int operator/(const big_int& a, const big_int& b) {
if (b.s=="") {
cout<<"error"<<endl;
exit(-);
}
big_int c;
big_int _a=a, _b=b;
_a.flag=_b.flag=;
if (m_cmp(_b.s,_a.s)) return c; stack <big_int> q;
big_int k=;
while () {
big_int x=k*_b; q.push(k);
if (m_cmp(x.s,_a.s))
break;
k=k*;
}
big_int tmp=_a;
while (tmp.s!=""&&!q.empty()) {
k=q.top(); q.pop();
big_int x=k*_b;
if ( !m_cmp(x.s,tmp.s)) {
tmp=tmp-x;
c=c+k;
}
}
if (a.flag^b.flag) c.flag=;
return c;
}
big_int operator%(const big_int& a, const big_int& b) {
big_int c=a/b;
c=c*b;
c=a-c;
return c;
}
int main ()
{
big_int a,b;
big_int c=-;
cout<<c<<endl;
while (cin>>a>>b) {
c=a+;
cout<<c<<" ";
c=a-b;
cout<<c<<" ";
c=a*b;
cout<<c<<" ";
c=a/b;
cout<<c<<" ";
c=a%b;
cout<<c<<endl;
}
return ;
}
大整数四则运算------(c++ 实现 乘法没有用傅里叶变换)的更多相关文章
- 大整数四则运算(vector与数组两种版本实现)
每逢大整数四则运算,都会怯懦,虽是算法竞赛必会的东西,也零散的学过,简单的总结过,但不成体系的东西心里一直没底. 所以今天消耗了大量的卡路里,啃了几套模板之后终于总结成了一套自己的模板 再也不用担心大 ...
- 大整数算法[09] Comba乘法(原理)
★ 引子 原本打算一篇文章讲完,后来发现篇幅会很大,所以拆成两部分,先讲原理,再讲实现.实现的话相对复杂,要用到内联汇编,要考虑不同平台等等. 在大整数计算中,乘法是非常重要的,因为 ...
- Code Kata:大整数四则运算—乘法 javascript实现
上周练习了加减法,今天练习大整数的乘法运算. 采取的方式同样为竖式计算,每一位相乘后相加. 乘法函数: 异符号相乘时结果为负数,0乘任何数都为0 需要调用加法函数 因为输入输出的为字符串,需要去除字符 ...
- 大整数算法[11] Karatsuba乘法
★ 引子 前面两篇介绍了 Comba 乘法,最后提到当输入的规模很大时,所需的计算时间会急剧增长,因为 Comba 乘法的时间复杂度仍然是 O(n^2).想要打破乘法中 O(n^2) ...
- [转]大整数算法[11] Karatsuba乘法
★ 引子 前面两篇介绍了 Comba 乘法,最后提到当输入的规模很大时,所需的计算时间会急剧增长,因为 Comba 乘法的时间复杂度仍然是 O(n^2).想要打破乘法中 O(n^2) ...
- Code Kata:大整数比较大小&大整数四则运算---加减法 javascript实现
大整数的四则运算已经是老生常谈的问题了.很多的库也已经包含了各种各样的解决方案. 作为练习,我们从最简单的加减法开始. 加减法的核心思路是用倒序数组来模拟一个大数,然后将两个大数的利用竖式进行运算. ...
- Code Kata:大整数四则运算—除法 javascript实现
除法不可用手工算法来计算,其基本思想是反复做减法,看从被除数里面最多能减去多少个除数,商就是多少. 除法函数: 如果前者绝对值小于后者直接返回零 做减法时,不需要一个一个减,可以以除数*10^n为基数 ...
- 大整数算法[10] Comba乘法(实现)
★ 引子 上一篇文章讲了 Comba 乘法的原理,这次来讲讲如何实现.为了方便移植和充分发挥不同平台下的性能,暂时用了三种不同的实现方式: 1.单双精度变量都有的情况. 2.只有单精度变量的情况. 3 ...
- C语言课程设计大整数运算
该大整数运算系统用于对有符号的位数不超过500位的大整数进行加.减.乘.除四则运算和计算N(0<=N<=10000)的阶乘.注意事项 : 1.操作期间,进行四则运算时若大整数为正数请 ...
随机推荐
- Oracle多个字段如何合并成一个字段显示
今天记录一下在oracle中多个字段如何和合并成一个字段,使用到符号“||” 1.组合查询的数据 1)组合前查询的语句 -- 组合前数据的字段 -- select A.MID CATE_ID,A.Co ...
- C/C++ 全局变量的访问
#include <iostream> using namespace std; ; int main(int argc, char **argv) { ; std::cout <& ...
- 关于datetimepicker只显示年、月、日的设置
如下是只显示月的sample code: <link rel="stylesheet" href="css/datetimepicker/bootstrap-dat ...
- map的key 为指针
STL中map的key能否用char *呢?当然可以! 在程序中需要用到一个map,本来是这样写的,map<string, int> mapStr; 为了追求效率,把string改成了ch ...
- laravel创建资源路由控制器
php artisan make:controller PhotoController --resource
- body中的onload()函数和jQuery中的document.ready()有什么区别?
1.我们可以在页面中使用多个document.ready(),但只能使用一次onload(). 2.document.ready()函数在页面DOM元素加载完以后就会被调用,而onload()函数则要 ...
- [HDU4585]Shaolin
Problem 问你一个数的前驱和后继 Solution Treap模板题 Notice 注意输出那个人的编号 Code #include<cmath> #include<cstdi ...
- linux 基础储备
ls命令是Linux下最常用的命令之一,ls跟dos下的dir命令是一样的都是用来列出目录下的文件,下面我们就来一起看看ls的用法ls /home 这个命令不但可以添加用户到系统,而且可以默认为新用户 ...
- RabbitMQ fanout类型的Exchange
就目前来说,Exchange是与消息发送端有关的,因为它可以指定将消息发送到哪个或哪些队列中. 本篇文章介绍的fanout类型就是指定将消息群发到与Exchange绑定的所有队列中. fanout这个 ...
- fast-rcnn里的一些具体内容
NMS:Non-Maximum Suppression(非极大值抑制) 假设从一个图像中得到了2000个region proposals,通过在RCNN和SPP-net之后我们会得到2000*4096 ...