基本算法
1、排序
(1) 快速排序
void quicksort(int *arr,int left,int right)
{
int i,j,mid,temp;
mid=arr[(left+right)>>1];
i=left;
j=right;
while(i<=j){
while(arr[i]<mid) i++;
while(arr[j]>mid) j--;
if(i<=j){
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
i++; j--;
}
}
if(i<right) quicksort(arr,i,right);
if(left<j) quicksort(arr,left,j);
}
(2)归并排序
void mergesort(int left,int right,int* A,int* temp)
{
if(left>=right) return ;
int mid=(left+right)/2; //划分左右两个区间
int p=left,q=mid,i=left;
mergesort(left,mid,A,temp);
mergesort(mid,right,A,temp); //递归
while(p<m || q<right){
if(q>=right || (p<m && A[p]<=A[q])) temp[i++]=A[p++];
//将左半部分复制到临时空间
else temp[i++]=A[q++];
//将右半部分复制到临时空间
}
for(i=left;i<right;i++) A[i]=temp[i];
//从临时空间复制回A数组
}
2、高精度计算
(1)高精度加法
note: 高精度计算中进位的处理应该是先做运算,然后再判断进位。
#include<stdio.h>
#include<string.h>
char a[1000],b[1000];
int ans[1000];
int main()
{
int i,j=0,lena,lenb,len,left=0;
// left为进位标记
scanf("%s%s",a,b);
if(a[0]=='0'&&a[1]=='\0'&&b[0]=='0'&&b[1]=='\0'){
printf("0");
return 0;
}
// 特判和为0的情形
else{
lena=strlen(a);
lenb=strlen(b);
if(lena<lenb){
len=lenb;
for(i=lena-1;i>=0;i--) a[i+len-lena]=a[i];
for(i=0;i<len-lena;i++) a[i]='0';
}
else if(lena>lenb){
len=lena;
for(i=lenb-1;i>=0;i--) a[i+len-lenb]=a[i];
for(i=0;i<len-lenb;i++) a[i]='0';
}
else len=lena;
// 两数右端对齐,位数少的前端补0
for(i=len-1;i>0;i--){
ans[i]=(a[i]-'0'+b[i]-'0'+left)%10;
// 先处理上一位的进位值,再更新当前进位值
if(a[i]-'0'+b[i]-'0'+left>=10) left=1;
else left=0;
}
ans[0]=a[i]-'0'+b[i]-'0'+left;
// 特判首位情形,输出无需模10
for(i=0;i<len;i++){
if(ans[i]==0) j++;
else break;
}
// 删除前端多余0
for(i=j;i<len;i++) printf("%d",ans[i]);
}
return 0;
}
(2) 高精度减法
note: 第二个可能比第一个大,是负数要输出负号。
#include<stdio.h>
#include<string.h>
char a[12000],b[12000],s1[12000],s2[12000];
int ans[12000];
int compare(char *a,char *b)
{
int i,lena,lenb;
lena=strlen(a);
lenb=strlen(b);
if(lena<lenb) return -1;
else if(lena>lenb) return 1;
else{
for(i=0;i<lena;i++){
if(a[i]>b[i]) return 1;
if(a[i]<b[i]) return -1;
}
return 0;
}
}
// compare函数判断a、b大小:若a>b,返回1;a<b,返回-1;a=b,返回0
int main()
{
int i,j=0,lens1,lens2,left=0;
// left设为借位值,若需借位,记作1,否则为0
scanf("%s%s",a,b);
if(compare(a,b)==0){
printf("0");
return 0;
}
else if(compare(a,b)==1){
strcpy(s1,a);
strcpy(s2,b);
}
else{
strcpy(s1,b);
strcpy(s2,a);
}
// s1存a、b中的大数,s2存a、b中的小数
lens1=strlen(s1);
lens2=strlen(s2);
for(i=lens2;i>=0;i--) s2[i+lens1-lens2]=s2[i];
for(i=0;i<lens1-lens2;i++) s2[i]='0';
// s1与s2右端对齐,s2前端空缺位补0
for(i=lens1-1;i>=0;i--){
s1[i]-=left;
// 计算前先减去借位值
if(s1[i]>=s2[i]){
left=0;
ans[i]=10*left+s1[i]-s2[i];
}
else{
left=1;
ans[i]=10*left+s1[i]-s2[i];
}
}
for(i=0;i<lens1;i++){
if(ans[i]==0) j++;
else break;
}
// 消去前端多余0
if(compare(a,b)==-1) printf("-");
for(i=j;i<lens1;i++) printf("%d",ans[i]);
return 0;
}
(3) 高精度乘法
#include<stdio.h>
#include<string.h>
char a1[1000],b1[1000];
int main()
{
int a[1000],b[1000],ans[2000];
int lena,lenb,lenans,i,j,overflow;
scanf("%s%s",a1,b1);
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(ans,0,sizeof(ans));
// 初始化数组
lena=strlen(a1);
lenb=strlen(b1);
for (i=0;i<lena;i++) a[lena-i]=a1[i]-48;
for (i=0;i<lenb;i++) b[lenb-i]=b1[i]-48;
// 将输入的字符串“逆序”转化为整型变量(ASCII)
for (i=1;i<=lena;i++){
overflow=0;
// 初始化进位
for(j=1;j<=lenb;j++){
ans[i+j-1]=a[i]*b[j]+overflow+ans[i+j-1];
// 模拟竖式算法,进位,错位相加
overflow=ans[i+j-1]/10;
// 先计算,后判进位
ans[i+j-1]%=10;
// 进位后保留个位
}
ans[i+lenb]=overflow;
// 最高位不用模10进位
}
lenans=lena+lenb;
while(ans[lenans]==0&&lenans>1) lenans--;
// 删除前端多余0
for(i=lenans;i>=1;i--) printf("%d",ans[i]);
// 逆序输出
return 0;
}