对string类和对象的操作
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
string str("123456789");
cout<<str<<endl;
return 0;
}
输出:
/
将字符数组转换成整形数组程序
int *Str2Int(char *str)
{
int i, len =strlen(str);
int *a=new int[(len+1)*sizeof(int)];
for(int i=0;i<len;i++) a[i]=str[len-i-1]-'0';
return a;
}
整数数组的归整运算(将a[k]中的数转换成p进制)
int check(int *a,int n)
{
int k=0,len=n;
while(a[len-1]==0&&len>1) len--;
for(int k=0;k<len;k++)
{
if(a[k]>=10)
{
a[k+1]=a[k+1]+a[k]/10;
a[k]=a[k]%10;
}
}
if(a[k]!=0) len=k+1; //确定数组最终长度
return len;
}
归整完毕后,可将整型数组再转换为字符数组,以备后用
char *Int2Str(int *a,int n)
{
int i;
char *str=new char[(n+1)*sizeof(char)];
for(int i=0;i<n;i++) str[i]=(char)a[n-i-1]+48; // a转换为字符数组str
str[n]='\0';
return str;
}
高精度四则运算的基本处理方法
对输入数据的处理:
数据小则直接存,大则用字符串存
接下来处理以下三个基本问题:
①计算结果位数的确定
②进位处理和借位处理
③商和余数额求法
加法
减法
两数A,B的减法处理方法有两种:从低位开始或从高位开始
常用的方法是从低位开始:
①确定差的位数:两数之差的位数不超过较大数的位数
②借位处理:做减法运算时,要先判断是否需要借位,如果需要借位那么从上一位借一个1,当作本位的10,上一位减1,然后本位相减
③负数的处理:如果减数B大于被减数A,那么交换A,B的值转化为被减数大于减数的情况处理
乘法
除法
除法是基于减法的方式,采用试商法。做除法运算时,每次都是用被除数减去商与除数的积,如果所得余数不为零,将其扩大10倍再次作为被除数,继续试除,直至余数为零或达到要求的精度为止。
在具体处理时,也可将除法转化为多位数乘1位数,这个多位数就是被除数。然后相加,在采用逐次减法的方法。
下面列出高精度四则运算的程序,每个程序都独立可用
const int MAXLEN = 1000;
// 加法:输入两个用字符数组表示的长整数m1,m2
// 返回一个字符数组指针,指向m1与m2的和
char *addition(char *m1, char *m2)
{
int i, len1, len2, len, c=0;
int * t1, * t2;
len1=strlen(m1);len2=strlen(m2);
len=(len1>=len2)?len1:len2; //定位数
t1=new int[(len+2)*sizeof(int)];
t2=new int[(len+2)*sizeof(int)];
t1=Str2Int(m1);
t2=Str2Int(m2);
for(i=len1;i<len+1;i++) t1[i]=0; //缺位前导补零
for(i=len2;i<len+1;i++) t2[i]=0; //缺位前导补零
for(i=0;i<len;i++) t1[i]=t1[i]+t2[i]; //加法
len=check(t1,len); // 归整
return Int2Str(t1,len); //转化为字符串,返回
}
// 减法:输入两个用字符数组表示的长整数m1,m2
// 返回一个字符数组指针,指向m1与m2的差
char *subtract(char *m1, char *m2)
{
int i, len1, len2, len, c=0, *t1, *t2, cf=0;
char *temp, *csub;
len=strlen(m1);len2=strlen(m2);
len=(len1>=len2)?len1:len2; // 定位数
t1=new int[(len+2)*sizeof(int)];
t2=new int[(len+2)*sizeof(int)];
temp=new char[(len+2)*sizeof(char)];
csub=new char[(len+3)*sizeof(char)];
if((len>len1)||((len2==len1)&&strcmp(m1,m2)<0)) // 当被减数小于减数时,调整
{
strcpy(temp,m1); //将m1复制到temp中
strcpy(m1,m2);
strcpy(m2,temp);
len1=strlen(m1);len2=strlen(m2);
cf=1;
}
t1=Str2Int(m1);t2=Str2Int(m2); // m1,m2分别转化为整型数组t1,t2
for(i=len1;i<len;i++) t1[i]=0;
for(i=len2;i<len;i++) t2[i]=0;
for(i=0;i<len;i++)
{
if(t1[i]>=t2[i]) t1[i]=t1[i]-t2[i];
else //归整
{
t1[i]=t1[i]-t2[i];
c=(t1[i]*(-1)%10)==0?(t1[i]*(-1)/10):(t1[i]*(-1)/10+1);
t1[i]=t1[i]+10*c;
t1[i+1]=t1[i+1]-c;
}
}
int n=i, begin =0;
while(t1[n-1]==0&&n>1) n--;
if(cf==1)
{
csub[0]='-';
n++;begin=1;
}
for(i=begin;i<n;i++) csub[i]=(char)t1[n-i-1]+48; // 将t1转化为字符数组csub
csub[n]='\0';
return csub;
}
// 乘法:输入两个用字符数组表示的长整数m1,m2
// 返回一个字符数组指针,指向m1与m2的积
char *multiply(char *m1,char *m2)
{
int i, j, len1, len2, len, c=0, *t1, *t2, *prod;
len1=strlen(m1);len2=strlen(m2);
len=len1+len2; // 定位数
t1=new int[(len1+1)*sizeof(int)];
t2=new int[(len2+1)*sizeof(int)];
prod=new int[(len+1)*sizeof(int)];
t1=Str2Int(m1);t2=Str2Int(m2);
for(i=0;i<len+1;i++) prod[i]=0; // 缺位前导补零
for(i=0;i<len1;i++)
for(j=0;j<len2;j++)
prod[i+j]=prod[i+j]+t1[i]*t2[j];
len=check(prod,len); //归整
return Int2Str(prod,len);
}
①高精度数除以高精度数的实现方法如下:
// 高精度数除以高精度数
// 输入两个用字符数组表示的长整数m1,m2
// 输出m1被m2除的商quotient和余数remainder
void divide(char *m1, char *m2, char *remainder, char *quotient)
{
int i, j, k, len, *temp;
int len1=strlen(m1), len2=strlen(m2);
char *m3;
if(strcmp(m1,m2)==0)
{
quotient[0]='1';
quotient[1]='\0';
remainder[0]='0';
remainder[1]='\0';
}
else if((len1<len2)||(len1==len2)&&strcmp(m1,m2)<0)
{
quotient[0]='0';
quotient[1]='\0';
remainder=m1;
}
else
{
temp=new int[(len2+1)*sizeof(int)];
len=0;
for(i=0;i<len1;i++)
{
temp[i]=0;
remainder[len]=m1[i];
remainder[len+1]='\0';
len=strlen(remainder);
while((len>len2)||((len==len2)&&(strcmp(remainder,m2)>=0)))
{ //即remainder>=m2
m3=new char[(len1+1)*sizeof(char)];
memset(m3,0,sizeof(m3));
m3=subtract(remainder,m2);//这里采用了逐次减法
remainder=m3;
len=strlen(remainder);
temp[i]++;
}
quotient[i]=temp[i]+'0';
}
j=0;
while((j<len1)&&(quotient[j]=='0'))
j++;
for(k=0;k<len1-j;k++)
quotient[k]=quotient[k+j];
quotient[len-j]='\0';
if(remainder[0]=0)
{
remainder[0]='0';
remainder[1]='\0';
}
}
}
②高精度数除以低精度数的实现方法如下:
关于delete[]
//new[] 必须配合delete[]使用,有时使用delete了不会报错(例如delete基本类型或者结构体等的数组指针)
string* pStr = new string[9];
delete[] pStr; //delete[]会逐个调用“对象数组”的每个对象的“析构函数”,这里用delete肯定报错(除非“这个类,没有析构函数”)
#define max 1000
// 高精度数除以低精度数
// 一下程序中,num是被除数,p是除数,remainder是余数,quotient是商
void HpDivByShort(string num,int p, int * remainder, string quotient)
{
int len = num.length(), i, s, *nn; //字符数据num转化为整型数组nn
nn = new int[len];
for(i=0;i<len;i++) nn[i]=num[i]-'0';
int tmp = 0, rem, tmp_q[max], flag=0;
i=0;
while((i<len)&&(tmp<p)) //准备试商
{
tmp=tmp*10+nn[i];
i++;
}
i--; // 商的位置
s=i; //最高位置i
tmp_q[i]=tmp/p; // 试商
rem= tmp%p; //取余
tmp=rem; // 准备与num的后续数构成新数
nn[i]=tmp_q[i];
while(i<len-1)
{
tmp=tmp*10+nn[i+1];
if(tmp<p)
{
tmp_q[i+1]=0;
nn[i+1]=0;
}
else
{
rem=tmp%p;
tmp_q[i+1]=tmp/p;
nn[i+1]=tmp/p;
tmp=rem;
}
i++;
}
*remainder=tmp;
for(i=0;i<len-s;i++)
{
tmp_q[i+s]+='0';
quotient[i]=tmp_q[i+s];
}
quotient[len-s]=0;
delete[]nn;
return;
}
Basic remains(计算余数)这题没有用到上面的模板