注册 登录
编程论坛 数据结构与算法

[原创]长整数的加减运算

starrysky 发布于 2005-09-24 16:22, 7264 次点击

Typedef struct node {

int data1; //存储系数 0<=data1<=9

unsigned long int data2; // 存储指数0~232-1

struct node *next;

struct node *pre;

}// node, *DuLinkList ;

status CreatList(DuLinkList &L) //长整数的输入与存储

{ char c[];

gets(c);//将长整数以字符串的形式输入

p=L . head; if (a[0]='-' or a[0]='+') { if(a[0]='-') L.head->data1=-1 ;//如果长整数为负,在链表头结点中标记为-1 else L.head->data1=1;//如果长整数为正,在链表头结点中标记为1 for (i=0; a[i]!=''; i++) a[i]= a[i+1]; }

else L.head->data1=1;//如果长整数为正,在链表头结点中标记为1

for(i=0 ; i<strlen(c) ; i++) //从数组转入链表并转化数据类型

{

if(a[i]>' 9 ' or a[i]< ' 0 ') exit ( ERROR INPUT);//出错处理

f(a[i]= ' 0 ') ;//如果当前数位上的数值为0, 则不建立该结点

else

{

r=(node *)malloc(sizeof (node));//分配空间

if(! r) exit (OVERFLOW);//分配失败,则出错

r->data1=a[i]-' 0 '; //数据类型转化 char to int

r->data2= strlen(c)-1-i;

p->next= r; r->pre =p;

p=r;

}

} free(c); //删除数组c return OK;

}// CreatList

void DeletCurElem(*p)//删除当前结点 { h=p->pre; h->next=p->next; p->next->pre=h; free(p); p=h->next; h=NULL; }

void JudgeCurElem(*q) //出理当前数位的进位退位 { h=q->pre; if(q->data1>9) { q->data1-=10; h->data1+=1; JudgeCurElem(h); if(q->data1=0) DeletCurElem(q); q=q->next; } if(0<q->data1<=9) q=q->next; if(q->data1=0) DeletCurElem(q); if(q->data1<0) { q->data1+=10; h->data1-=1; build(h,q);//建立h和p之间的结点 if(h->data1=0) DeletCurElem(h); q=q->next; } h=NULL; }

void build(*p, *q) { t=p; i=p->data2-q->data2-1; for(;i>0;i--)//分配i个空间 { r=(node *)malloc(sizeof (node)); if(! r) exit (OVERFLOW);//分配失败,则出错 r->data1= 9;

r->data2= q->data2+i;

t->next= r; r->pre =t;

t=r;

} t->next=q ; q->pre=t; t=NULL }

void output(DuLinkList &L) //输出函数 { printf("计算结果为:"); p=L.head->next; if(!p) //计算结果为0 printf("0"); else { if L.head->data1=-1 printf("-"); //如果为负数则输出负号 while(p) { printf("%d",p->data1); // 补充为0的数位 if(p->next) { p->data2-- ; while(p->data2!=p->next->data2) { printf("0"); p->data2--; } } if(!p->next&&p->data2!=0) while( p->data2!=0) { printf("0"); p->data2-- ; } p=p->next; } } }

void main() { InitList(La); InitList(Lb); printf(“请输入第一个长整数”); CreatList(La); printf(“请输入第二个长整数”); CreatList(Lb); printf(“请输入运算符”); c=getchar(); if( c= '+ '); if( c= '- ') Lb.head->data1*=-1; else exit(ERROR INPUT); a=La.head->data1; b=Lb.head->data1; qa=La.head->next; qb=Lb.head->next; while(qa and qb) //合并La, Lb { ha=qa->pre; hb=qb->pre; if(qa->data2>qb->data2) qa=qa->next;

if(qa->data2=qb->data2) { qa->data1=(qa->data1*a+qb->data1*b)/a; DeletCurElem(qb); }

if(qa->data2<qb->data2) //将qb插入到qa之前 { qb->data1=qb->data1*b/a; //将qb内数据转换为qa内数据 ha->next=qb; qb->pre=ha; hb->next=qb->next; qb->next=qa; qa->pre=qb; qb=hb->next; } }

if(!ListEmpty(Lb))//Lb 不为空时将其插入到La末尾 { ha->next=qb; qb->pre=ha; qa=ha->next; // qa=qb Lb.head->next=NULL; hb=NULL; while (qa) { qa->data1=qa->data1*b/a; //将qb内数据转换为qa内数据 } qb=NULL; free(Lb.head); } p=La.head->next; if(p->data1<0) { La.head->data1*=-1; while(p) {p->data1*=-1;p=p->next;} } p=La.head->next; while(p) JudgeCurElem(p);//重新遍历La, 进行进位退位处理 output(La); } 上面的算法为长整数的加法和减法运算, 稍微修改一下就可以上机调试.

11 回复
#2
starrysky2005-09-24 16:25
改一下定义的结构和部分语句就可以变成象

Typedef struct node {

int data1; //存储万以内的整数 -10000<data1<10000

unsigned int data2; // 存储指数,1 表示10000,2表示 100002,3表示100003,...

struct node *next;

struct node *pre;

}// node, *DuLinkList 这样的结构, 就是某些人的数据结构作业.我就不改了

#3
starrysky2005-09-24 16:42
2:题目:长整数四则运算。
问题描述:设计一个实现任意长的整数进行加法运算的演示程序。
基本要求:利用双向循环链表实现长整数的存储,每个结点含一个整形变量。任何整形变量的范围是 -(2^15 - 1)~ (2^15 - 1)。输入和输出形式:按中国对于长整数的表示习惯,每四位一组,组间用逗号隔开。
测试数据:
(1)0;0;应输出“0”。
(2)-2345,6789;-7654,3211;应输出“-1,0000,0000”。
(3)-9999,9999;1,0000,0000,0000;应输出“9999,0000,0001”。
(4)1,0001,0001;-1,0001,0001;应输出“0”。
*****************************************************
这个题目可用楼主的算法完成, 但用第2楼的结构比较好.
#4
starrysky2005-09-24 17:08
如果有问题 , 请不吝赐教
#5
蓝天2005-09-29 23:54
我的回复
我是个初学者,以后有时间一定多上来LOOK一下!
#6
myajax952006-06-03 14:43

好久不写这种程序了,熟熟手。只写了加减法,回头再写乘除。

程序代码:

#include <iostream>
#include <deque>
#include <string>
#include <sstream>
using namespace std;


class CLongInt;
CLongInt abs(CLongInt li);


namespace CLongIntDef
{
const int intDataSize = 4;
}


class CLongInt
{
public:
CLongInt(string sData);
string ToString() const;
bool operator > (CLongInt li);
CLongInt operator + (CLongInt li);
CLongInt operator - (CLongInt li);
CLongInt operator - ();
private:
deque<int> m_deqData;
bool m_bPositive;
};


CLongInt::CLongInt(string sData)
{
string sCurrent;
if (sData.at(0) == '+' || sData.at(0) == '-')
{
  m_bPositive = (sData.at(0) == '+');
  sData.erase(0, 1);
}
else
  m_bPositive = true;


while (sData.size() > 0)
{
  if ((int)sData.size() < CLongIntDef::intDataSize)
  {
   m_deqData.push_front(atoi(sData.c_str()));
   return;
  }
  else
  {
   sCurrent = string(sData, sData.size()-CLongIntDef::intDataSize, sData.size());
   sData.erase(sData.size()-CLongIntDef::intDataSize, sData.size());
   m_deqData.push_front(atoi(sCurrent.c_str()));
  }
}
}


string CLongInt::ToString() const
{
stringstream ss;
char charar[5];
int intCount;


if (!m_bPositive)
  ss << \"-\";
for (intCount = 0; intCount < (int)m_deqData.size(); intCount++)
{
  if (intCount == 0)
   ss << m_deqData[intCount];
  else
  {
   sprintf(charar, \"%04d\", m_deqData[intCount]);
   ss << charar;
  }
}
return ss.str();
}


bool CLongInt::operator > (CLongInt li)
{
int intCount;
if (m_bPositive > li.m_bPositive)
  return true;
else if (m_bPositive < li.m_bPositive)
  return false;


if (m_deqData.size() > li.m_deqData.size())
  return m_bPositive;
if (m_deqData.size() < li.m_deqData.size())
  return !m_bPositive;


for (intCount = 0; intCount < (int)m_deqData.size(); intCount++)
{
  if (m_deqData[intCount] > li.m_deqData[intCount])
   return m_bPositive;
  if (m_deqData[intCount] < li.m_deqData[intCount])
   return !m_bPositive;
}


return !m_bPositive;
}


CLongInt CLongInt::operator + (CLongInt li)
{
CLongInt &liResult = abs(*this) > abs(li) ? abs(*this) : abs(li);
CLongInt &liSmall = abs(*this) > abs(li) ? abs(li) : abs(*this);
int intCount, intData, intFirst, intSecond;


for (intCount = 0; intCount < (int)liSmall.m_deqData.size(); intCount++)
{
  intFirst = liResult.m_deqData[(int)liResult.m_deqData.size() - 1 - intCount];
  intSecond = liSmall.m_deqData[(int)liSmall.m_deqData.size() - 1 - intCount];
  if (m_bPositive ^ li.m_bPositive)
   intData = intFirst - intSecond;
  else
   intData = intFirst + intSecond;


  liResult.m_deqData[(int)liResult.m_deqData.size() - 1 - intCount] = intData%10000;
  if (intData >= 10000)
  {
   if (intCount == liResult.m_deqData.size()-1)
    liResult.m_deqData.push_front(1);
   else
    liResult.m_deqData[(int)liResult.m_deqData.size() - 2 - intCount] += 1;
  }
  else if (intData < 0)
  {
   liResult.m_deqData[(int)liResult.m_deqData.size() - 2 - intCount] -= 1;
   liResult.m_deqData[(int)liResult.m_deqData.size() - 1 - intCount] = 10000+intData;
  }
}
if (!(m_bPositive ^ li.m_bPositive))
  liResult.m_bPositive = m_bPositive;
else if (abs(*this) > abs(li))
  liResult.m_bPositive = m_bPositive;
else
  liResult.m_bPositive = li.m_bPositive;


while (liResult.m_deqData[0] == 0)
  liResult.m_deqData.pop_front();
return liResult;
}


CLongInt CLongInt::operator - (CLongInt li)
{
return *this + (-li);
}


CLongInt CLongInt::operator - ()
{
CLongInt liResult(this->ToString());
liResult.m_bPositive = !liResult.m_bPositive;
return liResult;
}


CLongInt abs(CLongInt li)
{
return li > CLongInt(\"0\") ? li : (-li);
}


ostream& operator << (ostream &o, CLongInt &li)
{
return o << li.ToString();
}



int main(int argc, char* argv[])
{
CLongInt in(\"123456789123\"), i2(\"1111111111111\");
cout << in+i2 << endl;
cout << in-i2 << endl;
return 0;
}

#7
starrysky2006-06-03 17:31
,这么早的帖子也给你翻出来了啊.
谢谢给出代码
可惜我学的是C,C++的看不大明白
我可是C++菜鸟级人物

[此贴子已经被作者于2006-6-3 17:41:28编辑过]

#8
菜鸟上路2006-06-03 20:42

顶!

#9
vitascl2007-04-12 21:10

用楼住所发代码编译出错
错误信息为:
--------------------Configuration: H1 - Win32 Debug--------------------
Compiling...
H1.cpp
C:\Documents and Settings\Administrator\桌面\0313425\H1.cpp(16) : error C2146: syntax error : missing ';' before identifier 'CreatList'
C:\Documents and Settings\Administrator\桌面\0313425\H1.cpp(16) : fatal error C1004: unexpected end of file found
执行 cl.exe 时出错.

H1.exe - 1 error(s), 0 warning(s)

我现在要用到这段代码 请高人指点!

#10
danielliujp2007-04-15 15:52
麻烦加点注释,谢谢了

#11
玻璃夕阳2007-06-20 12:12
请问能不能赐教一下啊?
怎样用C实现单链表的以下功能啊?
请赐教,十万火急啊!
功能:
使用单链表实现不限大小的整数,每个结点应该存储一位数字。在该单链表上实现大整数的加、减和乘运算。
#12
轩志2013-01-05 14:14
刚好最近我也在做这个,楼上的应该是C++的把,我用DEV C++运行不了。
1