两个长数字串全乘双向链表实现

来源:互联网 发布:python hangman游戏 编辑:程序博客网 时间:2024/05/17 01:59
//两个长数字串全乘双向链表实现
#include <iostream>
#include <cmath>
#include <stdlib.h>
using namespace std;


class DblList;
class DblNode{//双向链表结点类定义;
friend class DblList;
private:
        int data;
DblNode *lLink , *rLink ;
public:
       
       DblNode(int value,DblNode* left,DblNode *right):data(value),lLink(left),rLink(right){}
       DblNode(int value):data(value),lLink(NULL),rLink(NULL){}
};
//
class DblList{
public :
     DblList (int unique_Val) ;
     ~DblList () ;
     void input () ;//P 从键盘输入一串长整数构造双向循环链表
     int Length ( ) const ;//P 求链表中有效结点个数 ,即链表长度
     void Insertfront (const int & value) ;//P 将新元素插入到链表头
     void Insertrear (const int &value) ;//P 将新元素插入到链表尾
     void print () ;//P 打印输出链表表示的长整数
     void convolution (DblList&la ,DblList &lb) ;//P 求两数卷积运算
     void multiplication (DblList& ld) ;// P 卷积结果分离成商数;
private :
     DblNode *first;
};
//
DblList::DblList(int unique_Val){
     first = new DblNode (unique_Val) ;
     first->rLink = first->lLink = first ;
}


DblList::~DblList{
     DblNode * p , * q ;
     p =first - > rLink ;
     while (p ! =first) {
       q = p ;p = p - > rLink ;
       delete q ;
     }
     delete first ;
}


int DblLst ∷ Length () const{//P 求链表的长度(结点个数)
     DblNode  * p =first - > rLink ;
     int count = 0 ;
     while (p ! =first) {p = p - > rLink ;count + + ;}
     return count ;
}
void DblList ∷Insertrear (const int & value)//插入元素到链表尾
{   DblNode * p ;
     p = new DblNode (value) ;
     p - > rLink =first ;
     p - > lLink =first - > lLink ;
     first - > lLink - > rLink = p ;
     first - > lLink = p ;
}
void DblList ∷Insertfront (const int & value)// 插入元素到链表头
{
     DblNode * p ;
     p = new DblNode (value) ;
     if (first - > rLink = =first
     {   p - > rLink =first ;
        p - > lLink =first ;
        first - > lLink =first - > lLink = p ;
     }
     else
     {
         p - > lLink =first - > lLink ;
         p - > rLink =first ;
         first - > lLink - > rLink = p ;
         first - > lLink = p ;
     }
}
void DblList ∷ input () {//从键盘输入一串长数字串建立其对应的双向循环链表;
     char ch ;
     int chint ;
     int i = 0 ,k = 0 ;
     cout < <“请输入长数字串 ,按回车键或 Ctrl+ C结束:” ;
     while ( ! cin. eof () )
     {
     ch = cin. get () ;//接收从键盘输入的长数字串中的一个字符;
     if (ch = =‘P n’ ) break ;
     if (ch = =‘- ’ ) first - > data = - 1 ;
     else
     if (ch > =‘0’ &&ch < =‘9’ )
     {
       chint = ch -‘0’ ;
      Insertrear (chint) ;
      k + + ;
     }
     else if (ch = =‘.’ ) i = k ;
     else{
          cerr < <“输入错误 !”< < endl ;
          exit (1) ;
     }
     }
     if (i = = 0) i = k ;
     first - > data = (first - > data) * i ;
}
void DblList ∷ print () {//打印输出链表所对应的长整数
     DblNode * p ;
     int ij ,k ;
     p =first ;
     i = abs (first -> data) ;
     k =Length () ;
     cout < <“\ n长整数为:” ;
     if (p - > data < 0) 
        cout<<‘- ’ ;
     j = 0 ;
     while (p - > rLink ! =first) {
       p = p - > rLink ;
       cout < < p - > data ;
       j + + ;
       if (j = = i&& i ! = k) cout < <‘.’ ;
     }
     cout < <‘\ n’ ;
}


void DblList ∷conv olution (DblList& la , DblList &lb)//求两数的卷积结果
{
     DblNode * p1 , * p2 , * pp1 , * pp2 ;
     int c1 ,c2 ,c* ;
     c1 = la. first - > data ;
     c1 = la.Length () - abs (c1) ;
     c2 = lb. first - > data ;
     c2 = lb.Length () - abs (c2) ;
     c* = abs (c1) + abs (c2) ;
     
     if ( (la. first - > data) * (1b. first - > data) < 0)
     c* = c* * ( - 1) ;
     first - > data = c* ;
     p1 = la. first - > lLink ;p2 = lb. first - > lLink ;
     while (p2 ! = lb. first)
     {      pp2 = p2 ;
           int k = 0 ;
           pp1 = p1 ;
           while (pp2 ! = 1b. first & &pp1 ! = la. first)
           {
               k = k + (pp1 - > data) * (pp2 - > data) ;
               pp2 = pp2 - > rLink ;
               pp1 = pp1 - > lLink ;
           }
           Insertfront (k) ;
           p2 = p2 - > lLink ;
     }
     p1 = p1 - > lLink ; p2 = lb. first - > rLink ;
     while (pl ! = la. first)
     {
         pp1 = p1 ;
         pp2 = p2 ;
         int k = 0 ;
         while (pp1 ! = la. first &&pp2 ! = lb. first)
         {
                  k = k + (pp1 - > data) * (pp2 - > data) ;
                  pp1 = pp1 - > lLink ;
                  pp2 = pp2 - > rLink ;
        }
        Insertfront (k)
        p1 - p1 - > lLink ;
     }


}
void DblList ∷ multiplication (DblList&ld)//卷积结果分离成商数;
{
     DblNode * p ;
     int k ,ij = 0 ,c = 0 ;
     p = 1d. first - > lLink ;
     while (p ! = ld. first)
     {     k = c + p - > data ;
          i = k %10 ;
          c = kP 10 ;
          Insertfront (i) ;
          j + + ;
          p = p - > lLink ;
     }
     while (c ! = 0)
     {
       i = c %10 ;
       c = cP 10 ;
       Insertfront (i) ;
       j + + ;
     }
     k = ld. first - > data ;
     i = j - abs (k) ;
     first - > data = i ;
     if (k < 0)
         first->data = (first->data)*(-1) ;
}


void main () {
DblList pa (1) ;//构造初始双向循环链表pa
DblList pb (1) ;//构造初始双向循环链表pb
DblList pc (1) ;//构造初始双向循环链表pc
DblList pd (1) ;//构造初始双向循环链表pd
pa. input () ;//从键盘输入待计算的长整数串1并建立其对应的双向循环链表pa
pb. input () ;//从键盘输入待计算的长整数串2并建立其对应的双向循环链表pb
pc. conv olution (pa ,pb)//进行卷积运算并将其结果放在链表pc 中;


pd. multiplication (pc)// 将卷积结果转化为两数相乘的结果值放在双向链表pd中;
pd. print () ;// 输出结果值
}
/*运行结果示例
示例1 :
请输入长数字串 ,按回车键或 Ctrl + C结束:
12. 3456789012
请输入长数字串 ,按回车键或 Ctrl + C结束:
- 4567. 891234
12. 3456789012 3 - 4567. 891234 = - 56393.
7184305702320808
示例2 :
请输入长数字串 ,按回车键或 Ctrl + C结束:
1234567890
请输入长数字串 ,按回车键或 Ctrl + C结束:
23. 123456789
1234567890 3 23. 123456789 = 2854477257.
501905210


PS:
加法、 减法和除法等运算又如何实现呢 ? 用
带表头结点的双向循环链表表示的长数字串 ,对
于加、 减法运算 ,主要要处理好小数点对齐和进
位、 借位等问题 ,然后按位相加减即可实现;而对
于除法运算可以看成是除数的倒数乘以被除数 ,
即除法运算转化成乘法运算实现。如要求 x
y

值 ,我们可以把它看成是 x ×1
y
,而 1
y
可以用牛顿
法则的迭代计算公式: Ui+1 = Ui ×(2 - y ×Ui
) 进
行若干次迭代,根据精度要求精确到小数点后若
干位再与 x 相乘即可得到结果;迭代计算需要一
个初值 ,它必须满足大于0且小于1
y
的2倍 ,可通
过一个函数来实现。 限于篇幅,在此没有给出全部
程序。
*/
原创粉丝点击