對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;
}
題目:1005 大數加法
代碼:
// 這裏也考慮了負數的情況
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=1e4+10;
int main()
{
char a_str[maxn],b_str[maxn];
int a[maxn];
int b[maxn];
int c[maxn];
int a_ans,b_ans;
while(scanf("%s%s",a_str,b_str)==2){
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
int alen=strlen(a_str);
int blen=strlen(b_str);
if(a_str[0]=='-')
{
a_ans=-1;
//alen-=1;
for(int i=1;i<alen;i++)
{
a[i-1]=a_str[alen-i]-'0';
}
}
else
{
a_ans=1;
for(int i=0;i<alen;i++)
{
a[i]=a_str[alen-i-1]-'0';
}
}
//
if(b_str[0]=='-')
{
b_ans=-1;
//blen-=1;
for(int i=1;i<blen;i++)
{
b[i-1]=b_str[blen-i]-'0';
}
}
else
{
b_ans=1;
for(int i=0;i<blen;i++)
{
b[i]=b_str[blen-i-1]-'0';
}
}
///
int mx=max(alen,blen);
for(int i=0;i<mx;i++)
{
c[i]=a_ans*a[i]+b_ans*b[i];
}
for(int i=0;i<mx;i++)
{
if(c[i]>9)
{
c[i]-=10;
c[i+1]+=1;
}
if(c[i]<0)
{
c[i]+=10;
c[i+1]-=1;
}
}
int x=mx;
while( x>=0&&c[x]==0 ) x--;
if(x==-1)
{
printf("0\n");
}
else if(c[x]>0)
{
for(int i=x;i>=0;i--)
{
printf("%d",c[i]);
}
printf("\n");
}
else //是負數
{
for(int i=0;i<=x;i++)
c[i]=-1*c[i];
for(int i=0;i<=x;i++)
{
if(c[i]<0)
{
c[i]+=10;
c[i+1]-=1;
}
}
printf("-");
int t=x+3;
while(c[t]==0) --t;
for(int i=t;i>=0;i--)
{
printf("%d",c[i]);
}
printf("\n");
}
}
return 0;
}