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

📄 bignumclass.cpp

📁 能运算的函数: sin,cos,tg,ctg,e^,pow(x,y),cosh,sinh,tgh,log10,ln,sqrt,arcsin,arccos, 运算方式: +,-,*,/,绝对值(“[
💻 CPP
字号:
#include "stdafx.h"
#include  "BignumClass.h"
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>


//构造函数
BignumClass::BignumClass( char *Char ) 
{
  	 strcpy(str,Char) ;
}

//构造函数
BignumClass::BignumClass()
{
}

//析构函数
BignumClass::~BignumClass() 
{
     for(int i=0 ;i<100 ;i++)
		 str[i]='\0' ;
}


void BignumClass::translate_char()
{ 

	head = NULL ; 
	for(int i = 0 ; i < strlen(str) ;)
	{
		pnew=(struct  strArray *)malloc(sizeof(struct strArray)) ;//开辟新结点	 
		//pnew=new struct strData ;
        ///////////////////////////////结点初始化/////////////////////////////////
		if(head  ==  NULL)  { temp = head = pnew ;   temp  ->  before = NULL ; }  //是头结点
		else  //连结链表
		{
			pnew -> before = temp  ;
		    temp=temp -> next = pnew ;
		}

		arrayToZero(temp->nArray );//数组初值都为0
		temp -> cChar=' ' ;
		temp -> next=NULL ;//它的下一个结点没东西

		switch( str[i] )//对具体的字符以具体的处理
		{//switch
			
		    case '+' : 				   
				        temp -> nCharInt=1 ;//1表示是字符 0 是数字					
				        temp -> cChar='+' ;   //存相应的字符
						i++ ;
						break ;
					  
			case '-' :  temp -> nCharInt=1 ;  temp -> cChar='-' ; i++ ;break ; 
			case '*' :  temp -> nCharInt=1 ;  temp -> cChar='*' ; i++ ;break ; 
			case '/' :  temp -> nCharInt=1 ;  temp -> cChar='/' ; i++ ;break ; 
			case '!' :  temp -> nCharInt=1 ;  temp -> cChar='!' ; i++ ;break ; 
			case '(' :  temp -> nCharInt=1 ;  temp -> cChar='(' ; i++ ;break ; 
			case ')' :  temp -> nCharInt=1 ;  temp -> cChar=')' ; i++ ;break ; 
			case '^' :  temp -> nCharInt=1 ;  temp -> cChar='^' ; i++ ;break ; 
			case '[' :  temp -> nCharInt=1 ;  temp -> cChar='[' ; i++ ;break ;
			case ']' :  temp -> nCharInt=1 ;  temp -> cChar=']' ; i++ ;break ;
			case '=' :  temp -> nCharInt=1 ;  temp -> cChar='=' ; i++ ;break ;
			case ',' :  temp -> nCharInt=1 ;  temp -> cChar=',' ; i++ ;break ;
			case 'S' :  temp -> nCharInt=1 ;  temp -> cChar='S' ; i++ ;break ;//求和
			case 's' :  temp -> nCharInt=1 ;  temp -> cChar='s' ; i++ ;break ;
			case 'P' :  temp -> nCharInt=1 ;  temp -> cChar='P' ; i++ ;break ;//排列数
			case 'p' :  temp -> nCharInt=1 ;  temp -> cChar='p' ; i++ ;break ;
			case 'C' :  temp -> nCharInt=1 ;  temp -> cChar='C' ; i++ ;break ;//组合数
			case 'c' :  temp -> nCharInt=1 ;  temp -> cChar='c' ; i++ ;break ;
			case 'II':  temp -> nCharInt=1 ;  temp -> cChar='I' ; i=i+2 ;break ;//连乘
			
           
			default : 
				 
             /////////////////////处理 数字 字符串//////////////////// 
				temp -> nCharInt=0 ;//它是要存放数字的
                int top=0;
				int nput = i;
				 while( str[nput] >= 48 && str[nput] <= 57||str[nput] == '.')//计算整数和小数的位数
				 { 
					 if(str[nput] == '.') temp->nArray [0]=top;//0.7  top=1;;;有小数点了存一下整数的位数
				     top++;
					 nput++;
					
				 }
				 if(temp->nArray [0]==0)//没有.是一个整数
					 temp->nArray [0]=top;//存整数位数
				 else//有小数				 
					 temp->nArray [MAX-1]=top-temp->nArray [0]-1;//存小数位数

				 for(top=MAX*2/3-temp->nArray [0]+1;top<=MAX*2/3;top++)//把整数的各位按要求存入数组
				 {
					 temp->nArray [top]=str[i++]-48;//str[i++]-48 是由字符型的数字到int型的数字
				 }
				 if( temp->nArray [MAX-1]!=0)//有小数输入
				 {
					 i++;//跳过小数点
				     for(top=MAX*2/3+1;top<=MAX*2/3+temp->nArray [MAX-1];top++)//把小数的各位按要求存入数组
					 {
					     temp->nArray [top]=str[i++]-48;
					 }

				  }  
				 if(temp->nArray [0]==1&&temp->nArray [MAX*2/3]==0)temp->nArray [0]=0;//0.7刚才整数位是1;
				 break;

			}//end switch
			
	}//end for

}



////////////////////////////以下是求值///////////////////////////////////
///////////////     在这个类中我没有提供带()的四则混合运算       /////
//////////////    ()[]只作公倍数公约数的标记和函数的参数        /////
//////////////////////////////////////////////////////////////////////
void BignumClass::slove()//求值函数
{

	for( temp=head ;  temp-> next !=NULL  ; temp=temp-> next)
    {   //for	 
		if( temp-> cChar == '[')//[ ]是求最小公倍数的标记
		{ 
			 common_multiple(temp->next);//求最小公倍数
			 copyNode(temp,temp->next);
			 pnew=temp;
			 while(pnew->cChar !=']'){pnew=pnew->next ;}
			 deleteNode(temp ,pnew->next );
		}
	    if( temp-> cChar == '(')//   left=temp ;  // 记住左(的指针
		{
		   if(temp->before ==NULL)// '( '是在第一位出现肯定是最大公约数
		   {  
			   common_divisor(temp->next);			   
			   copyNode(temp,temp->next);
			   pnew=temp;
			   while(pnew->cChar !=')'){pnew=pnew->next ;}
			   deleteNode(temp ,pnew->next );
		   }
		   else
		   { // int p_m;
		       switch(temp->before->cChar )
			   {//c (15,3)
				   case 'c' :
				   case 'C' : 
					   int	 c_n;
					   int	 c_m;
					   c_m=arrToLong(temp->next ->next ->next-> nArray);
					   c_n=arrToLong(temp->next ->nArray);
					   permutation(temp->next ->nArray,c_n-c_m+1);//p(15,3)
					   permutation(temp->next ->next ->next-> nArray,1);//3!
                       arrDiv(temp->next ->nArray ,temp->next ->next ->next-> nArray  );

					   copyNode(temp->before,temp->next);
					   deleteNode(temp->before ,temp->next->next->next->next->next );
					   temp=temp->before ;
					   break;//是求组合数了C(5,3)=10
				  case 's' :
				  case 'S' : break;//是求连加了s(1,10,i)=55即1+2+……+9+10
				  case 'I' : break;//是求连乘了I(1,10,i)=3628800即1*2*……*9*10
				  case 'p' :
				  case 'P' :    //+p(5,3)-      只有p(5,3)
					   int   p_m;
					   p_m=arrToLong(temp->next ->next ->next-> nArray);                      
					   permutation(temp->next ->nArray,p_m);
					   copyNode(temp->before,temp->next);
					   deleteNode(temp->before ,temp->next->next->next->next->next );
					   temp=temp->before ;	
					   break;//是求排列数了P(5,3)=120

				  default : //是求最小公约数
					   break;
			  }  
		   }
	   }//if (
	 } //end for

////////////////////////////现在没有括号了

	


	for(temp=head ; temp->next !=NULL ; temp=temp->next )
	{
		switch(temp->cChar )
		{
		    case '/': 
				if(temp->next->nArray [0]==0&& temp->next->nArray [MAX-1]==0);//MessageBox("除数为0");
			    else 
				{		
	                arrDiv(temp->before->nArray ,temp->next->nArray  );
				    deleteNode(temp->before ,temp->next ->next );
			        temp=temp->before;			 
				}
			break;

		case '^': 
			long     a;
			if(temp->next ->nArray [MAX-1]!=0||temp->next ->nArray [0]==0)  ::AfxMessageBox(" 我不想计算不是整数的乘方和0次幂!!!!");
            a=arrToLong(temp->next ->nArray);
		    power(temp->before ->nArray,a);
			deleteNode(temp->before ,temp->next ->next );//去掉几个结点 +22^5-化为+5153632-
			temp=temp->before;
			break;
		case '!': 
			permutation(temp->before->nArray,1);
			deleteNode(temp->before ,temp->next);//去掉几个结点+n!-化为+n-
            temp=temp->before;
			break;
        case '*':			
            arrMul(temp->before->nArray ,temp->next->nArray  );//乘后存在temp->before->nArray中
			deleteNode(temp->before ,temp->next ->next );//去掉几个结点 +10*5-化为+50-
			temp=temp->before;
			break;
		default :
			break;
		
		}//end swi
	}//end for
//我没有为数组表示负数,故只能这样计算了

	temp = head;
	ArrayClass    arr_positive;
	ArrayClass    arr_minus;
	ArrayClass    arr_tmp;
	BignumClass   s;
	if(head->cChar =='-'){temp=temp->next ;s.copy (arr_minus.arr ,temp->nArray );}
	else s.copy (arr_positive.arr ,head->nArray );

	for(temp=temp->next ;temp->next !=NULL;temp=temp->next->next  )//现在只剩下+ -运算了,对a-b-c-d+e+f用a+e+f-(b+c+d)来求
	{//+22-23+43  or  -44+6546-544
	     s.copy (arr_tmp.arr ,temp->next ->nArray );	
	     if(temp->cChar =='-')  arr_minus=arr_minus+arr_tmp;
	     if(temp->cChar =='+'){arr_positive=arr_positive+arr_tmp;}
	     s.arrayToZero(arr_tmp.arr);
	}
	arr_positive=arr_positive-arr_minus;
	s.copy (head->nArray ,arr_positive.arr );
	  
}



void BignumClass::arrayToZero(int narr[])
{
	for(int i=0;i<MAX;i++)
      narr[i]=0;
}


void BignumClass::common_divisor(struct strArray *first)//求最大公约数(3,6,5), 3
{  
    struct strArray *pt;
    pt=first;
    ArrayClass      arrone;
	arrone.arr [MAX*2/3]=1;//arrone.arr  就是1所成的数组

	ArrayClass       arrtop;
	ArrayClass       arrmin;	
	ArrayClass       arrA(first->nArray );//第一个数
	ArrayClass      arrB(first->next ->next ->nArray );//第二个数
	

   while(1)
   {//3,6
		 arrone.compare(pt->nArray ,pt->next ->next ->nArray )==0?
			     copy(arrmin.arr ,pt->nArray):copy(arrmin.arr ,pt->next ->next ->nArray);//3,4
		 arrtop =  arrmin;
		 while(1)
		 {   
			arrtop=arrtop-arrone;
		    if((arrA%arrtop)==0&&(arrB%arrtop)==0)break;
		 }
		if((arrtop.arr [0]==1&&arrtop.arr [MAX*2/3]==1)||pt->next ->next ->next ->cChar ==')')
		{///arrtop 是1或者没有再要算的了
			copy(first->nArray ,arrtop.arr );  
			return;
		}
		else
		{//还要继续
			pt=pt->next ->next ;////pt----->6
			copy(pt->nArray ,arrtop.arr );//(3,6)=3--->6  -->  (3,5)
			copy(arrA.arr,pt->nArray);
			copy(arrB.arr,pt->next ->next ->nArray);
		}
   }



}


void BignumClass::common_multiple(struct strArray *first)//求最小公倍数
{//[3,5,6]
	struct strArray *pt;
    pt=first;
    ArrayClass arrone;
	arrone.arr [MAX*2/3]=1;//arrone.arr  就是1所成的数组
	ArrayClass arrtop;
	ArrayClass arrmax;
	
	ArrayClass arrA(first->nArray );//第一个数3
	ArrayClass arrB(first->next ->next ->nArray );//第二个数5

   while(1)
   {//3,5
      
		 arrone.compare(pt->nArray ,pt->next ->next ->nArray )==1?
			     copy(arrmax.arr ,pt->nArray):copy(arrmax.arr ,pt->next ->next ->nArray);//3,4
		 arrtop =  arrmax;
		 while(1)
		 {   
			
		    if((arrtop%arrA)==0&&(arrtop%arrB)==0) break;	
			arrtop=arrtop+arrone;
		 }
		if(pt->next ->next ->next ->cChar ==']')
		{///arrtop 没有再要算的了
			copy(first->nArray ,arrtop.arr );  
			return;
		}
		else
		{//还要继续
			pt=pt->next ->next ;////pt----->5
			copy(pt->nArray ,arrtop.arr );//[3,5]=15--->5  -->  [15,6]
			copy(arrA.arr,pt->nArray);
			copy(arrB.arr,pt->next ->next ->nArray);
		}
   }

}

void BignumClass::redressal(int  arr1[])//调整数组,使每位上数字不大于10
{
	int xx;
	for(int t=MAX-2;t>=1;t--)
	{
		if(arr1[t]==0)continue ;
		xx=arr1[t];     //324
		arr1[t]=xx%10;  //arr1[t]=4=324%10
		xx=xx/10;        //xx=32=324/10
		arr1[t-1]=arr1[t-1]+xx;
	}
	for(t=1;arr1[t]==0&&t<=MAX*2/3;t++);
   getDigit(arr1);
//	arr1[0]=MAX*2/3-t+1;
}






int BignumClass::zero(int arrdividend[])//被除数是否为0了
{
	for(int t=1;t<MAX-1;t++)
	{	
		if(arrdividend[t]!=0) return 0;
	}
   if(t==MAX-1)return 1;


}




void BignumClass::getDigit(int narr[])//得到长整数的整数和小数位数
{
	for(int t=1;t<=MAX*2/3;t++)
		if(narr[t]!=0)break;
	narr[0]=MAX*2/3-t+1;
	for(t=MAX-2;t>=MAX*2/3+1;t--)
		if(narr[t]!=0)break;
	narr[MAX-1]=t-MAX*2/3;
}

void BignumClass::copy(int keep[],int end[])//把end copy 给keep
{
  for(int t=0;t<MAX;t++)
	  keep[t] = end[t];
}
void BignumClass::deleteNode(struct strArray *first,struct strArray *second)//删除结点
{
	first->next =second;
	second->before =first;

}


void BignumClass::power(int arr[],long b)//计算arr^b;
{
	if((arr[0]-1)*b+1>MAX*2/3){::AfxMessageBox("你要我算的位数太大了!");return;}//error  估算肯定越位
	ArrayClass arr1(arr);
	ArrayClass arr2;
	arr2=arr1;
	for(int t=2;t<=b;t++)
	{	arr2=arr1*arr2;
	if(arr2.arr [1]!=0||arr2.arr [2]!=0||arr2.arr [3]!=0) {::AfxMessageBox("你要我算的位数太大了!");return;}
	}

	copy(arr,arr2.arr );	

}


long BignumClass::arrToLong(int arr[])//把arr化为long
{  long		nlong=0;
   int	    k=1;
	for(int t=MAX*2/3;t>MAX*2/3-arr[0];t--)
	{
		nlong=nlong+arr[t]*k;
	    k=k*10;
	}
	return nlong;
}


void BignumClass::permutation(int narr[],int m)//p(n,m)求排列
{
   int		n=arrToLong(narr);
   if((n-m-1)*narr[MAX-1]>MAX*2/3) {::AfxMessageBox("你要我算的位数太大了!");return;}//error  估算可能越位

	ArrayClass		arr1(narr);
	ArrayClass		arrtmp;
	ArrayClass		arrone;
	arrone.arr [MAX*2/3]=1;//arrone.arr  就是1所成的数组

	arrtmp=arr1;
    arr1=arr1-arrone;//n=n-1

	for(long t=n-1;t>=m;t--)
	{
		arrtmp=arrtmp*arr1;
		if(arrtmp.arr [1]!=0||arrtmp.arr [2]!=0||arrtmp.arr [3]!=0) {::AfxMessageBox("你要我算的位数太大了!");return;}//error  估算可能越位
		arr1=arr1-arrone;
	}

  copy(narr,arrtmp.arr );



}

void BignumClass::copyNode(struct strArray *keep,struct strArray *tmp)//结点拷贝tmp的内容给keep
{
	keep->cChar =tmp->cChar ;
	copy(	keep->nArray ,tmp->nArray );
	keep->nCharInt =tmp->nCharInt ;
}


void BignumClass::arrMul(int arrfir[],int arrsec[])//两处数组相乘
{
	
	ArrayClass arr1(arrfir);
    ArrayClass arr2(arrsec);
	arr1=arr1*arr2;
    copy(arrfir,arr1.arr );
}

void BignumClass::arrDiv(int arrfir[],int arrsec[])//两处数组相除
{
	ArrayClass arr1(arrfir);
    ArrayClass arr2(arrsec);
	arr1=arr1/arr2;
    copy(arrfir,arr1.arr );
}








//如果p(n,m),n!,a^b 中n,m,b,太大就不要运算了

⌨️ 快捷键说明

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