您的位置:首页 > 其它

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

2011-08-23 23:56 211 查看
//两个长数字串全乘双向链表实现

#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倍 ,可通

过一个函数来实现。 限于篇幅,在此没有给出全部

程序。

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: