1. 程式人生 > >利用迴圈連結串列表示大整數 C語言

利用迴圈連結串列表示大整數 C語言

這是大一時學C語言程式設計所做的一個簡單問題。參考了網上部分程式碼並加入了自己編寫的減法程式碼,程式還是存在一定的問題,無法處理負超長整數,還有待完善。但是按照老師的話就是題目中並沒有明確要求,算是專了題目的空子 o(∩_∩)o... 這個程式算是入門吧。

問題描述: 

利用迴圈連結串列表示大整數 連結串列的頭結點值為-1,其餘結點依次存放資料,各結點最多存放四位整數。如下表示233238766
-1
2
3323
8766
在利用上述資料結構完成大整數的表示後,實現兩個大數的加法,減法運算(兩個連結串列表示運算元) 原始碼: #include<stdio.h> #include<stdlib.h> #define HUNTHOU 10000 typedef struct node {        int data;
       struct node *next; }NODE; /*定義連結串列結構*/ /*輸入超長整數,存入連結串列*/ NODE *inputint(void) {        NODE *s,*ps,*qs;        struct number        {               int num;               struct number *np;        }*p,*q;        int i,k;        long sum;        char c;        p=NULL; /*指向輸入的整數,鏈首為長整數的最低位,鏈尾為長整數的最高位
*/        while((c=getchar())!='/n') /*輸入整數,按字元接收數字*/        if(c>='0'&&c<='9') /*若為數字則存入*/        {               q=(struct number *)malloc(sizeof(struct number)); /*申請空間*/               q->num=c-'0'; /*存入一位整數*/               q->np=p; /*建立指標*/               p=q;        }        s=(NODE *)malloc(sizeof(NODE));        s->data=-1; /*建立表求超長正整數的鏈頭*/        ps=s;        while(p!=NULL) /*將接收的臨時資料鏈中的資料轉換為所要求的標準形式*/        {               sum=0;i=0;k=1;               while(i<4&&p!=NULL) /*取出低四位*/               {                      sum=sum+k*(p->num);                      i++;                      p=p->np;                      k=k*10;               }               qs=(NODE *)malloc(sizeof(NODE)); /*申請空間*/               qs->data=sum; /*賦值,建立連結串列*/               ps->next=qs;               ps=qs;        }        ps->next=s; /*指向頭結點*/        return s; } /*u結點後插入一個新的NODE,其值為num*/ NODE *insert_after(NODE *u,int num) {        NODE *v;        v=(NODE *)malloc(sizeof(NODE)); /*申請一個NODE*/        v->data=num; /*賦值*/        u->next=v;/*u結點後插入一個NODE*/        return v; } NODE *addint(NODE *p,NODE *q) /*完成加法操作返回指向*p+*q結果的指標*/ {        NODE *pp,*qq,*r,*s,*t;        int total,number,carry;        pp=p->next;        qq=q->next;        s=(NODE *)malloc(sizeof(NODE)); /*建立存放和的連結串列表頭*/        s->data=-1;        t=s; carry=0; /*carry:進位*/        while(pp->data!=-1&&qq->data!=-1) /*均不是表頭*/        {               total=pp->data+qq->data+carry; /*對應位與前次的進位求和*/               number=total%HUNTHOU; /*求出存入鏈中部分的數值 */               carry=total/HUNTHOU; /*求進位*/               t=insert_after(t,number); /*將部分和存入s指向的鏈中*/               pp=pp->next; /*分別取後面的加數*/               qq=qq->next;        }        r=(pp->data!=-1)?pp:qq; /*取尚未自理完畢的鏈指標*/        while(r->data!=-1) /*處理加數中較大的數*/        {               total=r->data+carry; /*與進位相加*/               number=total%HUNTHOU; /*求出存入鏈中部分的數值*/               carry=total/HUNTHOU; /*算出進位*/               t=insert_after(t,number); /*將部分和存入s指向的鏈中*/               r=r->next; /*移動指標*/        }        if(carry) t=insert_after(t,1); /*處理最後一次進位*/        t->next=s; /*指向頭結點*/        return s; /*返回指向和的結構指標*/ } /*比較兩個數的大小*/ int compare(NODE *p,NODE *q) {        NODE *pt,*qt;        int i=1,j=1;     int k;        pt=p->next;        qt=q->next;        while(pt->next->data!=-1) {pt=pt->next;i++;} /*計算多少個結點*/        while(qt->next->data!=-1) {qt=qt->next;j++;} if(i==j) {        while(pt->data!=-1)        {        if(pt->data-qt->data>0) return 1;        if(pt->data-qt->data<0) return 0;   /*p指標指向數鏈大於等於q,函式返回1否則返回0*/               for(k=0;k<i;k++)               {                      pt=pt->next;                      qt=qt->next;               }        }        return 1; } if(i>j) return 1; else return 0; } /*完成兩個連結串列減法操作返回指向|*p-*q|結果的指標*/ NODE *subint(NODE *p,NODE *q) {        NODE *pr,*qr,*s,*t;        int total,borrow; /*borrow:借位*/        if(compare(p,q))        {pr=p->next;qr=q->next;} /*pr指向較大的數鏈,qr指向較小的數鏈*/        else {pr=q->next;qr=p->next;}        s=(NODE *)malloc(sizeof(NODE));        s->data=-1;        t=s;borrow=0;        while(qr->data!=-1)        {               total=pr->data-qr->data-borrow;               if(total<0)     /*有借位*/               {                      total=HUNTHOU+pr->data-qr->data-borrow;                      borrow=1;               }               else borrow=0;               if(pr->next->data!=-1)               t=insert_after(t,total);               else{                      if(total!=0) t=insert_after(t,total); /*最高位為0時不存入求差鏈中*/               }               pr=pr->next;qr=qr->next;          }        while(pr->data!=-1) /*處理餘下結點*/        {               total=pr->data-borrow;               if(total<0)               {                      total=HUNTHOU+pr->data-borrow;                      borrow=1;               }               else borrow=0;               if(pr->next->data!=-1)               t=insert_after(t,total);               else{                      if(total!=0) t=insert_after(t,total);               }               pr=pr->next;        }        t->next=s;        if(s->next->data==-1) /*處理位數小於等於4位且相減結果為0情況*/        {               t=insert_after(t,total);               t->next=s;        }                   return s; } /*列印連結串列*/ void printint(NODE *s) {        if(s->next->data!=-1) /*若不是表頭,則輸出*/        {               printint(s->next); /*遞迴輸出*/               if(s->next->next->data==-1)               printf("%d",s->next->data); /*列印最高位*/               else{                      int i,k=HUNTHOU;                      for(i=1;i<=4;i++,k/=10) /*按字元輸出不足4位補0*/                      putchar('0'+s->next->data%(k)/(k/10));               }        } } void main() { NODE *s1,*s2,*s,*g; int f; char c; NODE *inputint(), *addint(), *insert_after(),*subint(); do{        printf("Enter S1= ");        s1=inputint();        printf("Enter S2= ");        s2=inputint();        printf(" S1="); printint(s1); putchar('/n');        printf(" S2="); printint(s2); putchar('/n');        s=addint(s1,s2); /*求和*/        printf("S1+S2="); printint(s); putchar('/n'); /*列印結果*/        f=compare(s1,s2);        g=subint(s1,s2); /*求差*/        printf("S1-S2=");        if(!f) printf("-"); /*判斷符號*/        printint(g); putchar('/n');        printf("Enter key to continue other key to Exit:"); }while(c=getchar()=='/n'); } 六.除錯記錄 6.1測試資料分析: Enter S1= 5000 Enter S2= 5000  S1=5000  S2=5000 S1+S2=10000 S1-S2=0 Enter key to continue other key to Exit: Enter S1= 533 Enter S2= 1481  S1=533  S2=1481 S1+S2=2014 S1-S2=-948 Enter key to continue other key to Exit: Enter S1= 12341234 Enter S2= 12349843  S1=12341234  S2=12349843 S1+S2=24691077 S1-S2=-8609 Enter key to continue other key to Exit: Enter S1= 123456789 Enter S2= 987654322  S1=123456789  S2=987654322 S1+S2=1111111111 S1-S2=-864197533 Enter key to continue other key to Exit: Enter S1= 65432 Enter S2= 9541  S1=65432  S2=9541 S1+S2=74973 S1-S2=55891 Enter key to continue other key to Exit: 6.2結果分析: 1)在輸入長整數時如果輸入的內容不是0-9之間的數字,而是其他字元,系統將忽略字母或符號。               2)對進位和借位執行結果都正確無誤。高位相減為0時,最高位前面不會有0出現。               3)通過連結串列對於超長整數的計算執行結果同樣正確。