1. 程式人生 > >c++ 大整數乘法

c++ 大整數乘法

 #include<iostream.h>
#include<stdio.h>
#include<math.h>

struct Dnode{
 int data;
 Dnode *prv;
 Dnode *next;
};

class Bigint
{
public:
 Dnode *head,
  *p,
  *q,
  *r;
public:
 void input();
 void shaw();
 void clear();
 void insert(int n);
 void output(Bigint &b);
 Bigint(){
  head=new Dnode;
  head->prv=NULL;
      head->next=NULL;
  head->data=NULL;
 }
 Bigint(Bigint &a);
 ~Bigint(){
    r=this->head;
  while(r!=head){
   p=r;
   delete p;
   r=r->next;
  } 
 }
 friend Bigint operator +(Bigint& a,Bigint& b);
 friend Bigint operator *(Bigint& a,Bigint& b);
 Bigint operator = (const Bigint &BigNum);
 
};

Bigint::Bigint(Bigint &a){  //拷貝構造
 this->head=new Dnode;
 p=head;
 q=a.head;
 r=a.head->next;
 this->head->next=NULL;
 this->head->prv=NULL;
 
 while(r!=a.head){
  Dnode *b=new Dnode;
  b->next=head;
  b->data=r->data;
  p->next=b;
  b->prv=p;
  head->prv=b;
  r=r->next;
  p=b;
 }
}
Bigint Bigint::operator = (const Bigint &a)//過載=
{
 this->head->next=this->head->prv=NULL;
 if(this==&a)
  return *this;
 Dnode *m;
    m=a.head->prv;
 while(m!=a.head)
 {
  this->insert(m->data);
  m=m->prv;
 }
 return *this;
}
void Bigint::insert(int n){//插入運算,只在頭結點後插入
 
 Dnode *x=new Dnode;
 x->data=n;
 if(head->next==NULL){
  head->next=x;
  x->next=head;
  x->prv=head;
  head->prv=x;
 }
 else{
  r=head->next;
  x->next=r;
  x->prv=head;
  r->prv=x;
  head->next=x;
 }
 
}

void Bigint::input(){//字串輸入
 
 char  c;
 int i=0,sum=0;
 p=head;
 fflush(stdin);      //清空快取

 while( (c=getchar())!=10 ){
  Dnode *m=new Dnode;
  m->data=int(c-48);//轉換整數0~9
  p->next=m;//插入到結點中保留,一個結點只存一位
  head->prv=m;
  m->prv=p;
  m->next=head;
  p=m;
 }
 
}
void Bigint::shaw(){//顯示
 p=head;
 while(p->next!=head){
     p=p->next;
  cout<<p->data;
  
 }
 cout<<endl;
}
Bigint  operator +(Bigint& a,Bigint& b){//過載+
  int sum=0,y=0;//sum是本位和,y是進位
  Bigint temp;
  Dnode *m=new Dnode;
  Dnode *n=new Dnode;
  m=a.head->prv;
  n=b.head->prv;

   while(m!=a.head&&n!=b.head)//當加數、被加數都不為空時
   {
    sum=n->data+m->data+y;
    y=sum/10;
    sum=sum%10;
    temp.insert(sum);
    m=m->prv;
    n=n->prv;
   
   
   }
     while(n!=b.head)//加數不為空時
   {
    sum=n->data+y;
    y=sum/10;
    sum=sum%10;
    temp.insert(sum);
    n=n->prv;
   
  
   }
   while(m!=a.head)//被加數不為空時
   {
    sum=m->data+y;
    y=sum/10;
    sum=sum%10;
    temp.insert(sum);
    m=m->prv;
  
   }
  
  if(y==1)//判斷最後一次是否加進位
   temp.insert(y);
  

  return temp;
 

   void Bigint::clear(){//頭節點置空

 this->head->prv=NULL;
 this->head->next=NULL;
}


Bigint operator *(Bigint& a,Bigint& b){//過載乘

 int sum=0,y=0,q=0,t=0;//sum為本位積,y為進位、q為記數,乘了幾次
  Bigint temp,c;
  Dnode *m=new Dnode;
  Dnode *n=new Dnode;
  Dnode *w=new Dnode;
  m=a.head->prv;
  n=b.head->prv;
  c.insert(0);//先初始化
  while(n!=b.head){//當乘數不為空,迴圈乘被乘數
   if(q==0)//如果是第一次乘時
   {
    while(m!=a.head)//當被乘數不為空
    {
     sum=n->data*m->data+y;
     y=sum/10;
     sum=sum%10;
     temp.insert(sum);
     m=m->prv;
    }
  
    if(y!=0){//判斷最後一次是否有進位
     temp.insert(y);
     y=0;
    }
   }
   else{//不是第一次乘
    t=q;
    while(t-1!=0)//初始化c,進行對應的以為,即在末尾插入0
    {
     t--;
     c.insert(0);
    }
    while(m!=a.head)//當乘數不為0時
    {
     sum=n->data*m->data+y;
     y=sum/10;
     sum=sum%10;
     c.insert(sum);
     m=m->prv;
    }
  
    if(y!=0){
     c.insert(y);
     y=0;
    }
    temp=temp+c;//將本次乘法結果與上次相加,結果存在temp中。
    c.clear();//清空c
    c.insert(0);//再初始化c
   }
     
   q++;//記錄乘幾次
  
   n=n->prv;//乘數後移
   m=m->prv;//被乘數復位
  }
 
 
  return temp;
}

void main(){
 Bigint a,b,d;
 int q;
 
  cout<<"請輸入要選擇的操做,0為退出,1為加法,2為乘法:"<<endl;
 cin>>q;
 while(q!=0)
 {switch (q){
 case 1:
  {
   printf("請輸入a:");
         a.input();
        printf("請輸入b:");
   b.input();
   cout<<"a=";
   a.shaw();
   cout<<"b=";
   b.shaw();
  cout<<"a+b=";
  d=a+b;
  d.shaw();
  cout<<"計算成功,請重新選擇操作"<<endl;
  cin>>q;
 
  }break;
 case 2:
  {
   printf("請輸入a:");
         a.input();
        printf("請輸入b:");
   b.input();
   cout<<"a=";
   a.shaw();
   cout<<"b=";
   b.shaw();
  cout<<"a*b=";
  d=a*b;
  d.shaw();
  cout<<"計算成功,請重新選擇操作"<<endl;
  cin>>q;
 
 
  } break;
 case 0:
 
  break;
 
 
 default:{
   cout<<"輸入錯誤,請重新選擇操作:"<<endl;
   cin>>q;
 }
}
 }
}

相關推薦

c++ 整數乘法

 #include<iostream.h>#include<stdio.h>#include<math.h> struct Dnode{ int data; Dnode *prv; Dnode *next; }; class Bigint{

C/C++ 整數乘法

題目描述 求兩個不超過200位的非負整數的積。 輸入 有兩行,每行是一個不超過200位的非負整數,沒有多餘的前導0。 輸出 一行,即相乘後的結果。結果裡不能有多餘的前導0,即如果結果是342,那麼就不能輸出為0342。 樣例輸入 12345678900 9876

C語實現格子乘法--整數乘法

之前看過有博主發過python版的,看了一看覺得這個方法好玩,小時候老師教的時候又總聽不懂,就想試試看能不能實現起來。 具體的這篇部落格也寫的很清楚了,在這就具體說一說我這個演算法的思路好了。 1.讓使用者輸入兩個大整數以及它們的長度。 2.建立一個二維陣列

分治法實現整數乘法C++語言】

如果實現傳統演算法中兩個n位整數相乘,第一個整數中的n個數字都要分別乘以第二個整數的n個數字,這樣就一共要做n*n次乘法。看上去設計一個乘法次數少於n*n的演算法是不可能的,但事實證明並非如此,可以使用分治的思想計算兩個大整數的相乘。 首先從僅有兩位數字的兩個數12和34考慮,12 = 1 *

分治法優化整數乘法 C++實現

上大學演算法分析實驗課的內容.關於利用分治法大整數乘法.還沒有解決大整數的儲存方式,應該是要利用一維陣列來解決.所以目前只是5位數的運算沒有問題.程式不是很健全,但是演算法的核心部分應該是已經都在這裡了. VC++6.0下測試通過. #include <iostream

C/C++程式演算法小練習--整數乘法

大整數乘法的原理很簡單,就是模擬經典的手算步驟 #include <iostream> #include <cstring> using namespace std; void reverse_str(char *a,int size){ for(

2980 整數乘法

沒有 程序代碼 pre != return 註意 string str1 改變 題目來源:http://bailian.openjudge.cn/practice/2980/描述求兩個不超過200位的非負整數的積。輸入有兩行,每行是一個不超過200位的非負整數,沒有多余的前

light oj 1024 - Eid 整數乘法

imp borde mean ron [] public ans test case cas In a strange planet there are n races. They are completely different as well as their food

Multiply Strings整數乘法

height image 分析 特殊情況 pac 什麽 .com 總結 pos [抄題]: 以字符串的形式給定兩個非負整數 num1 和 num2,返回 num1 和 num2 的乘積。 [暴力解法]: 時間分析: 空間分析: [思維問題]: 還要找到結果中第一位不等於

caioj1450:【快速傅裏葉變換】整數乘法

rose clas scan name 代碼 printf 答案 r+ 傅裏葉變換 【傳送門:caioj1450】 簡要題意:   給出兩個超級大的整數,求出a*b 題解:   Rose_max出的一道FFT例題,卡掉高精度 = =   只要把a和b的每一

整數乘法

space ret algorithm 進行 cout while 當前 ostream cstring #include<cmath> #include<cstdio> #include<cstring> #include&l

21位水仙花,C++整數

首先宣告,接觸這個問題時候,大整數類,我還不大知道,所以,找了網上的原始碼看了一下思路,自己敲了一遍,給後來人參考。 執行時間51s, #include <iostream> #include <algorithm> #include <time.h> u

關於整數乘法和加法的一些整理

例如,有兩個大整數,a和b,其中a、b位數都是大於10的。我們知道,在做OJ的題時,碰到大整數的乘法,不能直接用a*b得到結果,那樣是不對的,所以需要用陣列來儲存。 首先,很簡單,定義兩個陣列(足夠長),s1和s2,分別用來儲存大整數a和b,因為我們需要用來相乘,而乘法是從最後一位開始

分治演算法解決整數乘法問題

整數相乘:小整數相乘在演算法時間分析中可以認為是常數時間,但是對於大整數,時間需要考慮。兩個N位數的整數X和Y相乘,常規方法花費時間是,因為X的每一位都要和Y的每一位相乘,是兩層迴圈。 分治演算法解決整數相乘問題: 例如,X是12345678,Y是87654321,將X和Y都拆成兩半,得到

演算法與設計經典題:整數乘法(教材2-4)

給定兩個整數u和v,他們分別有m和n為數字,且m≤n,用通常的乘法求uv的值需要O(mn)時間,可以將u和v均看作是有n位數字的大整數,用本章介紹的分治法,在O(n^(log3))時間內計算uv的值,當m<<n時,此法效率不高。設計演算法在O(nlog2/3)時間計算uv的值 在O(

分治法 整數乘法

學習演算法的時候,其中一道經典就是大整數乘法咯,感覺有點難理解,於是寫一篇部落格加深下理解。 大數相乘不可以直接得到答案,肯定會超出數的範圍,而解決大數相乘的辦法就是分治法:將大問題變成小問題,再變成簡單問題,最後進行合併。 例如:        

【演算法】整數乘法

大整數乘法 問題描述 求兩個不超過200位的非負整數的積。 輸入形式 有兩行,每行是一個不超過200位的非負整數,沒有多餘的前導0。 輸出形式 一行,即相乘後的結果。結果裡不能有多餘的前導0,即如果結果是342,那麼就不能輸出為0342。 樣例輸入 123456789

整數乘法中的分治思想(TOOM-COOK的一種使用方法)

演算法分析與設計學習中,接觸到一道大整數乘法問題,分享出來,原題目如下: 演算法分析在用分治法求兩個n位大整數u和v的乘積時,將u和v都分割為長度為n/3的3段。證明可以用5次n/3位整數的乘法求得uv的值。按此思想設計大整數乘積的分治方法,並分析演算法的計算

借陣列實現整數乘法

思想: 用字串來控制輸入,陣列來儲存,陣列的低位存整數的低位,高位來儲存高位, 和:計算的過程基本上和小學生列豎式做加法相同。 差:跟和差不多 乘:計算的過程基本上和列豎式做乘法相同。為程式設計方便,並不急於處理進位,而將進位問題留待最後統一處理 除:基本的思想

Java實現整數乘法

請設計一個有效的演算法,可以進行兩個n位大整數的乘法運算 1 最暴力的方法:O(n^2) 2 我們採用分而治之的思想 將X和Y按如下方法分成兩部分 那麼 X = A*10^(n/2) + B Y = C*10^(n/2) + D X*