⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 updatados2007.cpp

📁 大数运算的设计与实现
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include <iostream.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include <iomanip.h>
#define maxlength 99999//定义静态数组开辟的最大空间
#include <fstream.h>
ifstream in_stream;
ofstream out_stream;
 typedef struct Node    // 定义一个双向链表用来存贮结果
{
char data;     // 数据定义为字符的原因:要显示负号
Node *next;    // 尾指针
Node *ahead;   // 首指针
}big_numnode;

 class bignum_operation{
 
 private:         
				    int i;//变量用于合法性检查时的标识数位 
				    
					int n_inter,n_small;//用于求大数整数位数和小数位数
	                    
					big_numnode *r,*t;
					
					int sign;//在大数比较时标志大数的大小
					
					int  n_smallpoint;//当不能整除时设置保留小数点后的尾数个数
					
                    big_numnode *yushu;
 public:		 
					char *pa;
				
					char keysave[5];
				
					int k;
 public:   
			big_numnode *  creatlinklist( char a[]);// 创建双向链表用来存储大数
           
			bool bignum_check(char str);// 大数合法性检查
		   
			big_numnode * big_numADD(char a[],char b[]);//大数加法
             
			big_numnode * big_numADD(big_numnode *rear1,big_numnode *rear2, int n1,int n2,int n3,int n4,int op);//大数加法具体操作 
            
			big_numnode *big_numADD(big_numnode *rear1,big_numnode *rear2, int op);//大数加法具体操作
			  
			big_numnode *big_numnodeinsert(big_numnode * p,int i,int n, char c );//结点插入操作 

            void linklist_print(big_numnode * h);//链表输出
        
			int big_numCOMPARE(big_numnode * rear1,big_numnode * rear2);//大数绝对值的比较
              
			 big_numnode * big_numSUB(char  str[],char str2[]);//大数减法
            
			 big_numnode * linklist_length(big_numnode * rear);//用于求连表长度 
		
			  big_numnode * big_numMUL(char  str[],char str2[]);//大数乘法
		
			  big_numnode * big_numMUL(	 big_numnode *r, big_numnode *t);//大数乘法
	
		   big_numnode *  big_numMUL1(big_numnode * r,char b);//大数乘法乘数位数字与被乘数相乘
			
		   big_numnode *MULmoveleft(big_numnode *rear,int n,int f);//乘法移位操作
			  
		   big_numnode *deletpoint(big_numnode *p);//删除小数点操作
			 
		   big_numnode *addpoint(big_numnode *r,int i);//乘除法增加小数点操作
			 
		   big_numnode * big_numDEVIDE(char  str[],char str2[]);//大数除法
           
		   big_numnode * big_numDEVIDE( big_numnode *rear1, big_numnode *rear2);//大数除法

		   int isZERO(big_numnode *r);//用于除法运算时除数是否为零判断
			   
		   big_numnode * getlinknode( big_numnode * r,int n);//得到链表某个节点
			  
		   big_numnode * deletezero(  big_numnode * r);//删除链表头节点到第一个非零节点间的零
			
		   big_numnode *big_numSUB(big_numnode *r ,big_numnode *t );//大数减法
		
		   big_numnode *functionchoice(char a[],char b[],char f);//根据操作符号选择运算函数
			
		   big_numnode * big_numENCHANGE(char a[],char f );//大数进制转换函数
		
		   big_numnode *big_numPOWER(char a[],char b[]);//大数乘方运算
			
		   big_numnode *big_numPOWER(char a[],int i);//大数乘方运算
		   
			   void readFILE(char filename[]);//文件读取函数
				
		   void writeFILE(char filename[],big_numnode *t,int i);//文件读取函数
			
		   bignum_operation();//构造函数
               
		   ~bignum_operation();//析构函数
 
 } bignum_operation ;

   /**///////////////////////////////////////////////////////////////////////////
      
     //factorial类
  //  Purpose:         计算n!的值
  /**///////////////////////////////////////////////////////////////////////////
  
   
 class factorial{
                 public:

                   int GetNumber(char a[]);                                   //输入 n 
                   
				   int GetBitLength(int n);                           //求n!的位数
                   
				   char* Initialize(int);                             //初始化存储结果的值
                  
				   char * PrintValue(char *a,int size);                 //打印值到屏幕
                   
				   void PrintValue(char *a,int size,char* fileName);  //打印值到文件
                   
				   char* GetValue(int val);                           //计算
                   
				   char* SubGetValue(char* ,int);                      
				  
				   char *factorialcomputer(char a[],int i);
				       
				   factorial();
                       
				   ~factorial();
				
				 public:
							char *pp;
							
							int size;
							
							char *pa;
							
							int value;
							
							char fileName1[20];
 
 }factorial;


 factorial::factorial()
 {
		pp=NULL;
	
		size=0;
		
		value=0;
 
 }

factorial::~factorial()
 {
 
delete []pp; 
 
 }

/**///////////////////////////////////////////////////////////////////////////
      
     //arrange类
  //  Purpose:         计算C(a,b)的排列组合的值
  /**////////////////////////////////////////////////////////////////////////

 class  arrange{

 public:    
            
	big_numnode *arrangecomputer(char a[],char b[]);
	
	readFILE(char filename[],char*);		
	
	arrange();	

	~arrange();	
 
 public:
	
  char h1[maxlength];
  
  char h2[maxlength];
  
  char h3[maxlength];
  
  char op2;
  
  char a1[20];
  
  char b1[20];

 }arrange;
 arrange::arrange()//构造函数
	{

	}
 arrange::~arrange()//析构函数
	{
	
	}

 arrange::readFILE(char filename[],char *a3)//文件读取函数	
{
	char  filenum;
	
	int j=0;
	
	in_stream.open( filename);
	
	if(in_stream.fail())
	 {
		cout<<filename<<" file open faild.\n";
  
	 }

		in_stream>>filenum;

while(!in_stream.eof())
{
	a3[j]=filenum;
	
	j++;

	in_stream>>filenum;

}
	a3[j]='\0';
 
	in_stream.close();

}


big_numnode *arrange:: arrangecomputer(char a[],char b[])//排列组合的实现
 {
	char c[100];//存减数

	big_numnode *p;

	big_numnode *s=bignum_operation.big_numSUB( a, b);//大数减法	

	int k=0;
	
	if(s->data=='0'&&s->next!=NULL)
		
		s=s->next;
	
while(s){
		    c[k]=s->data;
		
			p=s;
			
			s=s->next;
			
			k++;
			
			free(p);
	}
		
		c[k]='\0';//得到排列组合计算时的做分母的减数
		
		char* a1=factorial.factorialcomputer(a,1);   //得到a的阶乘

		readFILE(factorial.fileName1,h1);
	
		char*b1=factorial.factorialcomputer(b,1);//得到b的阶乘

		readFILE(factorial.fileName1,h2);
	
		char*c1=factorial.factorialcomputer(c,1);//得到减数的阶乘
	
		readFILE(factorial.fileName1,h3);
	
		big_numnode *t=bignum_operation.big_numDEVIDE(h1,h2);//大数除法
	
while(t->ahead->ahead)//找到头节点 
	
	t=t->ahead;
	
	k=0;
while(t&&t->data!='.'){
		 
	h1[k]=t->data;//a2 此时用于存储第一次除得的商
	
	p=t;
	
	t=t->next;
		
	k++;
		
	free(p) ;
	}
	h1[k]='\0';

	t=bignum_operation.big_numDEVIDE(h1,h3);//大数除法

	return t;
 }
  //函数GetValue
  // 求得计算结果
 //返回结果
//1)char* GetValue()
//2)GetValue(int val)
// 参数:val 计算阶乘的值
 char* factorial::GetValue(int val)
 {
     //定义一个数组存储阶乘的值
		int VALUE=val; 
		
		int length=GetBitLength(VALUE);
		
		char *arrValue = new char[length]; 
    if(!arrValue) {
         
		cout <<"申请内存失败!" << endl; 
         
		exit(1); 
     } 
     arrValue[0] = 1; 
     
	 for(int i=1; i<length; i++) 
     arrValue[i] = 0; 
     
	 arrValue=SubGetValue(arrValue,VALUE);
     
	 return arrValue;
 }
 
 char* factorial::SubGetValue(char* arrValue,int n)
 {
     int index=0;
     
	 long carrier=0;
     
	 double bitCount = 1; 
     
	 int begin = 0; 
  
     for(index=2; index<=n; ++index) 
     { 
         long multiValue = 0;   
         
		 bitCount += log10((long double)index); 
         
		 if(arrValue[begin] == 0) 
            
			 begin++; 
  
         for(int j=begin; j<int(bitCount); ++j) 
         { 
             
			 multiValue += (index*arrValue[j]); 
             
			 arrValue[j] = char(multiValue % 10); 
             
			 multiValue /= 10; 
         } 
     } 
   return arrValue;
 }
 
 //得到计算阶乘的值,此函数为新增
 int factorial::GetNumber(char a[]) 
 { 
	 
	 char ch=a[0];
  
	 int i=0;
  
	 int tokenval=0;
	while(-1<(ch-'0')&&(ch-'0')<10)
			{
				tokenval=tokenval*10+ch-'0';
					i++;
				ch=a[i];
		
	}
	 
    if(tokenval == 0)         exit(1); 
    
	return tokenval; 
} 

//函数GetBitLength
// 求得计算结果的位数,本函数为新增加
//参数
//     n 需要计算的阶乘的数
//返回结果的位数
int factorial::GetBitLength(int n) 
{ 
    double sum = 1.0; 
    
	for(int i=1; i<=n; i++) 
        
		sum += log10((long double)i);
  
	return int(sum); 
} 
//-----------
//函数:Initialize
//   初始化存储结果的数组
//参数:
//     size      数组的长度  
//返回值
//    初始化后的数组
//-------------
char * factorial::Initialize(int size) 
{ 
    char *arrValue = new char[size];
    
	if(!arrValue) {
       
		cout << size<<"太大,申请内存失败!" << endl; 
       
		exit(1); 
    } 
    arrValue[0] = 1; 
    
	for(int i=1; i<size; i++) 
       
		arrValue[i] = 0; 
    return arrValue; 
} 
  
//-----------
//函数:PrintValue
//   将结果输入到屏幕上
//参数:
//     buff      存储结果的数组
//   buffLen   数组的长度
//   fileName  文件名         
//-------------
char * factorial::PrintValue(char *buff, int buffLen) 
{ 
  
    for(int i=buffLen-1; i>=0; i--) { 
      
          cout << int (buff[i]);   
       
    } 
    cout << endl; 
  
	return buff; 
} 

//-----------
//函数:PrintValue
//   将结果输入到一个文件中
//参数:
//     buff      存储结果的数组
//   buffLen   数组的长度
//   fileName  文件名         
//-------------

void factorial::PrintValue(char *buff,int buffLen,char *fileName)
{
     
    FILE *fp=NULL;
    //-----------------------------

    if (fileName==NULL)        return ;
     fp=fopen(fileName,"wt");
    if (fp==NULL)
    {
        printf("不能创建文件%s",fileName);
        return ;
   }

	for(int i=buffLen-1; i>=0; i--)
    {
       fprintf(fp,"%d",int (buff[i]));   
    }
    fprintf(fp,"\n");
   
	fclose(fp);
}

char* factorial::factorialcomputer(char a[],int i)
{// i=1 标志不用读到DOS界面直接存文件,i=0,读出并存文件
    
		value=GetNumber(a);
    
		 char fileName[16];
    
		size=GetBitLength(value);
   
		 pa = Initialize(size);

		pa=GetValue(value);
 
	if(i==0)
 
		pp=  PrintValue(pa,size); 

		sprintf(fileName,"%d!.txt",value);	
		
		strcpy(fileName1,fileName);
	
		PrintValue(pa,size,fileName);

 
return pp;


}





/**///////////////////////////////////////////////////////////////////////////
// bignum_operation类
     
//  Purpose:         计算大数四则运算,乘幂,数值转换 
/**///////////////////////////////////////////////////////////////////////////




bignum_operation:: bignum_operation()//构造函数
 {
 i=0;sign=0;
 
 n_inter=0;n_small=0;

n_smallpoint=5;

 }
bignum_operation:: ~bignum_operation()//析构函数
 {


 }
	big_numnode *bignum_operation::big_numPOWER(char a[],int i)//大数乘方运算
    {
	
	big_numnode *r,*p;  //  存储创建的两个链表的尾结点
    
	int j=0; 
	
	p=r=creatlinklist(a);// 创建双向链表
	
int 	tokenval=i;

if(tokenval==0)
{p=creatlinklist("1");// 创建双向链表

return p;
}
	while(j<tokenval-1)
	
	{ 
		p=big_numMUL(p,r);//大数乘法
	 
		j++;
	}
return p;
	
	}




	big_numnode *bignum_operation::big_numPOWER(char a[],char b[])//大数乘方运算
    {
	
	big_numnode *r,*p;  //  存储创建的两个链表的尾结点
    
	int j=0; 
	
	p=r=creatlinklist(a);// 创建双向链表
 
	char ch=b[0];
  
	int i=0;
  
	int tokenval=0;

	while(0<(ch-'0')&&(ch-'0')<9)
			{
				tokenval=tokenval*10+ch-'0';
					i++;
				ch=b[i];
		
			}


	if(tokenval==0)
{p=creatlinklist("1");// 创建双向链表

return p;
}


	while(j<tokenval-1)
	
	{ 
		p=big_numMUL(p,r);//大数乘法
	 
		j++;
	}
return p;
	
	}



big_numnode *bignum_operation::  big_numENCHANGE(char a[],char f)
{//进制转换函数,实现十进制到二,八,十六 进制的转换
	//a[n]是传入大数,f 是转换类型标志,b,o,x
           
		big_numnode *p,*q,*r;
		
		char c[5];
		int j=0;
		int k=0;
		if(f=='b'||f=='B')
		{
		strcpy(c,"2");
		}
		else if(f=='o'||f=='O')
		{
	    strcpy(c,"8");
		}
		else if(f=='X'||f=='x')
		{
		strcpy(c,"16");
		}
		else {
		cout<<"输入字符非法!!"<<endl;
			exit(0);
		
		}
          p=creatlinklist(a);// 创建双向链表
          r=creatlinklist(c);// 创建双向链表
		   q=new  big_numnode;//用于存储商的头结点
		  q->data='0';
		  q->ahead=q->next=NULL;
		  j=big_numCOMPARE(p,r);//大数绝对值的比较
          while(j==1)
		  { 
 	        p=big_numDEVIDE(  p, r);//大数除法取得整数部分商 
		 
			if(f=='x')
			if(yushu->ahead->ahead!=NULL)	
			{
			if(yushu->data=='0')
				yushu->data='A';
            if(yushu->data=='1')
				yushu->data='B';
            if(yushu->data=='2')
				yushu->data='c';
            if(yushu->data=='3')
				yushu->data='D';
			if(yushu->data=='4')
				yushu->data='E';
            if(yushu->data=='5')
				yushu->data='F';
			}	
            q=big_numnodeinsert(q,1,1, yushu->data);//从节点插入
		//	p=deletezero( p);//去掉头部多余零
		  // r=deletezero(r);//去掉头部
           j=big_numCOMPARE(p,r);//大数绝对值的比较
		  
		  }
		   
	       q=big_numnodeinsert(q,1,1,p->data);//结点插入操作 
	       q=big_numnodeinsert(q,0,1,f);//结点插入操作 
	       return q;
}



 big_numnode * bignum_operation::deletezero(  big_numnode * r)
{//删除链表头节点到第一个非零节点间的零,i=0 时r是尾指针,i=1时r 是头节点
   big_numnode * p,*q,*s;
   p=r;
   
   while(p->ahead!=NULL){
       q=p;
	   p=p->ahead;
     }//找到头节点
  
   
   while(q->data=='0'&&q->next!=NULL){
   p->next=q->next;
   q->next->ahead=p;
   s=q;
   q=q->next;
   free(s);
   }
   
   
   
   
   return r;

 }
 big_numnode * bignum_operation:: getlinknode( big_numnode * r,int n)
 {//得到链表某个节点,r 是尾指针,从后向前遍历,n 是走的节点数
 big_numnode * p;
 p=r;
 int i=0;
 while(i<n){
	 p=p->ahead;
	 i++;
 }
 
 return p;
}
int bignum_operation::isZERO(big_numnode *r)//用于除法运算时除数是否为零判断
 {//r 是尾指针,是零返回 0,否则返回 非零
big_numnode *p;
int i=0;
p=r;
while(p->ahead!=NULL){
	if(p->data=='0'||p->data=='.')p=p->ahead;
	else {
		i++;
		return  i ;}


}
return  i ;
}
 
big_numnode *bignum_operation:: big_numDEVIDE(big_numnode *r,big_numnode *t)//大数除法
{
big_numnode *p,*q,*r1,*r2,*r3;  //  存储创建的两个链表的尾结点
   int n=0; int i=0;//记录移位次数
   int j=0;
   int m=0;
   
   char c;
   linklist_length( r);//返回r的头指针
   int n1=n_inter;//存储链表r整数部分位数
   int n2=n_small;//存储链表r小数部分位数
   linklist_length( t);//返回t的头指针
   int n3=n_inter;//存储链表t整数部分位数
   int n4=n_small;//存储链表t小数部分位数
   if(n2!=0)
   r= deletpoint(r);//删除小数点操作
   if(n4!=0)
   t= deletpoint(t);//删除小数点操作
   r=deletezero( r);//去掉头部多余零
   t=deletezero( t);
   int zero=isZERO(r);
   if(zero==0)return r;
	 zero=isZERO(t);
	 if(zero==0)//合法性检查
	 {cout<<"除数不能为零"<<endl;
	 exit(0);
	 }
	 n=n3+n4;
	 m=n1+n2;
  
	 p=new  big_numnode;//用于存储商的头结点
		p->data='0';
		p->ahead=p->next=NULL;
	    j= big_numCOMPARE(r,t);//大数绝对值的比较
	 
         r1=getlinknode(r,m-n);
		 r2=r1->next;
         q=r1;
         q->next=NULL;
while(r3!=NULL)//控制总的循环次数
{
 j= big_numCOMPARE(q,t);//大数绝对值的比较
while(j==1){
	
		 q=big_numSUB(q,t);
		 q->next=NULL; 
		 q=deletezero( q);//去掉头部多余零
		 t=deletezero( t);//去掉头部
         j= big_numCOMPARE(q,t);//大数绝对值的比较
		 i++; 

          yushu=q;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -