两个长数字串全乘双向链表实现
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倍 ,可通
过一个函数来实现。 限于篇幅,在此没有给出全部
程序。
*/
#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倍 ,可通
过一个函数来实现。 限于篇幅,在此没有给出全部
程序。
*/
相关文章推荐
- 使用递归来实现双向链表里删除第一节点不是数字‘2’
- 剑指offer 01-06解答思路以及代码(顺序数组找特定数字,替换空格字符,链表反转输出,重建二叉树,两个栈实现队列效果,旋转数组最小元素)
- java数据结构之LinkedDeque(用链表实现的双端(即头尾两个哨兵节点)双向(node里两个指向)队列)
- Java实现双向链表(两个版本)
- 链表实现两个数字相加
- 简单双向链表(C++模版技术实现)
- 链表实现两个大正整数相加
- (C++版)链表(四)——实现双向循环链表创建、插入、删除等简单操作
- C实现带头节点带环双向链表的操作
- C++实现双向链表的创建,插入,修改,删除
- C++实现两个已经排序的链表进行合并
- C#实现双向链表
- 驱动下的双向链表实现 -----------------抄自张帆的书
- C++ 构造双向链表的实现代码
- Java双向链表的实现
- c++实现双向链表
- 双向链表的C语言实现与基本操作(一)
- C语言实现链表之双向链表(八)删除尾结点
- 有两个升序排列的数组A1和A2,给A1开辟的剩余内存有足够空间容纳A1,请实现一个函数,把A2中所有数字插入到A1中,并且是按照升序排列的
- LinkedList : 双向链表与实现