常用算法
来源:互联网 发布:淘宝79的牛仔裤 编辑:程序博客网 时间:2024/05/16 04:35
常用算法
写一个函数,将一个整数转化为字符串。
void itoa(int I,char str[])
{
inta,b,k=0;
chartemp;
if(I==0){str[0]='0';str[1]='/0';return;}
while(I>0)//关键部分
{
a=I%10;
I/=10;
str[k++]=a+'0';
}
b=k;
for(a=0;a<k/2;a++){
temp=str[a];
str[a]=str[--b];
str[b]=temp;
}
str[k]='/0';
}
用递归求最大公约数
intgcd(int n,int m)
{
if(n<m){//交换m和n
n=m+n;
m=n-m;
n=n-m;
}
if(n%m==0)return m;
gcd(m,n%m);
}
/*****************************************/
/*函数功能: 正负十制数转换成任意数制*********/
/*参数:i:为要转换的数 d:进制(d<=16)****/
/*返回值:无******************************/
/*****************************************/
void decToN(int i, int d,char str[],int k)
{
static char *c="0123456789abcdef";//包括十六进制
int I=i>0?i:-i;
if(I==0){
if(k==0)str[k++]='0';//输入0时
str[k]='/0';
return;
}
decToN(i>0?I/d:-I/d, d,str,k+1);//递归实现
str[k]=c[I%d];
if(k==0){//字符串逆序
for(int m=0,b=strlen(str);m<strlen(str)/2;m++)
{
char temp=str[m];str[m]=str[--b];str[b]=temp;
}
if(i<0){//输入为负数时
for(int m=strlen(str)+1;m>0;m--)
str[m]=str[m-1];
str[0]='-';
}
}
}
写一个程序,要求功能:求出用1,2,5这三个数不同个数组合的和为100的组合个数。
设x是1的个数,y是2的个数,z是5的个数,number是组合数
注意到0<=x<=100,0<=y<=50,0<=z=20,所以可以编程为:
void count()//方法一
{
number=0;
for (x=0; x<=100; x++)
for (y=0; y<=50; y++)
for (z=0; z<=20; z++)
if ((x+2*y+5*z)==100)
number++;
cout<<number<<endl;
}
因为x+2y+5z=100所以x+2y=100-5z,且z<=20 x<=100y<=50 所以(x+2y)<=100,且(x+5z)是偶数,对z作循环,求x的可能值
void count()//方法二
{
number=0;
for (int m=0;m<=100;m+=5)
{
number+=(m+2)/2;
}
cout<<number<<endl;
}
判断字符串是否为回文串
int IsSymmetry(char* s)
{
int len=0;
char *h=s;
for(len=0;*h!='/0';){h++;len++;}
for(int i=0,j=len;i<len/2;i++)
if(s[i]!=s[--j])return 0;
return 1;
}
判断一个数时候为回文数(如35653)
unsigned char Symmetry(long n)
{
long i,temp;
i=n; temp=0;
while(i) //不用出现长度问题,将数按高低位掉换
{
temp=temp*10+i%10;
i/=10;
}
return(temp==n);
}
求2~2000的所有素数.有足够的内存,要求尽量快
#define MaxLen 2001
void Sieve(int *List[],int n)
{
int list[MaxLen];
int p,i,j;
for(i=0;i<MaxLen;i++)list[i]=1;
for(p=2;p*p<=n;p++){//令pfrom 2 to n^0.5
if(list[p]){
j=p*p;
while(j<=n){
list[j]=0;
j+=p;
}
}
}
list[0]=list[1]=0;
for(i=0,j=0;i<n;i++){//存入数组List
if(list[i])
(*List)[j++]=i;
}
while(j<n)(*List)[j++]=0;
for(i=0;i<n;i++)//打印
if((*List)[i])printf("%d,",List[i]);
}
实现大正数(包括浮点数)相加
void Addtion(char *a,char *b,char **ret)
{
int Alen=0,Blen=0;
int APlen=-1,BPlen=-1;//小数部分长度
int Pflag=0;
for(char *p=a;*p!='/0';p++){
if(*p=='.')Pflag=1;
Alen++;
if(Pflag)APlen++;
}
for(p=b,Pflag=0;*p!='/0';p++){
if(*p=='.')Pflag=1;
Blen++;
if(Pflag)BPlen++;
}
int A=0,B=0,C=0;//进位标志
int Rlen=0;
while(Alen>0||Blen>0){
A=B=C=0;
if(Alen&&APlen>=BPlen)A=a[--Alen]-'0';
if(Blen&&BPlen>=APlen)B=b[--Blen]-'0';
if(a[Alen]!='.'&&b[Blen]!='.'){
(*ret)[Rlen++]=(A+B+C)%10+'0';
C=(A+B+C)/10;
}
else (*ret)[Rlen++]='.';//存储小数点
if(APlen!=BPlen)APlen>BPlen ? APlen--:BPlen--;
}
if(C>0)(*ret)[Rlen++]=C+'0';
(*ret)[Rlen]='/0';
for(int i=0,j=Rlen;i<Rlen/2;i++){//字符串逆序
char temp=(*ret)[i];
(*ret)[i]=(*ret)[--j];
(*ret)[j]=temp;
}
printf("%s/n",*ret);
}
实现大正数(包括浮点数)相减
void Subtract(char *a,char *b,char **ret)
{
int Alen=0,Blen=0;
int APlen=-1,BPlen=-1;//小数部分长度
int Pflag=0,Hflag=0;//默认b大于a
for(char *p=a;*p!='/0';p++){
if(*p=='.')Pflag=1;
Alen++;
if(Pflag)APlen++;
}
for(p=b,Pflag=0;*p!='/0';p++){
if(*p=='.')Pflag=1;
Blen++;
if(Pflag)BPlen++;
}
if(Alen-APlen>Blen-BPlen||(Alen==Blen)&&a[0]>b[0])//a>b
Hflag=1;
int A=0,B=0,D=0,C=0;//借位标志
int Rlen=0;
while(Alen>0||Blen>0){
A=B=D=0;
if(Alen&&APlen>=BPlen)A=a[--Alen]-'0';
if(Blen&&BPlen>=APlen)B=b[--Blen]-'0';
if(a[Alen]!='.'&&b[Blen]!='.'){
if(Hflag)D=A-B-C;
else D=B-A-C;
if(D<0){
D+=10;
C=1;
}
(*ret)[Rlen++]=D+'0';
}
else (*ret)[Rlen++]='.';//存储小数点
if(APlen!=BPlen)APlen>BPlen ? APlen--:BPlen--;
}
if(C>0&&(*ret)[Rlen-1]=='0')--Rlen;//清除第一个0
if(!Hflag)(*ret)[Rlen++]='-';
(*ret)[Rlen]='/0';
for(int i=0,j=Rlen;i<Rlen/2;i++){//字符串逆序
char temp=(*ret)[i];
(*ret)[i]=(*ret)[--j];
(*ret)[j]=temp;
}
printf("%s/n",*ret);
}
实现大正整数乘法
void Multiply(char *a,char *b,char **ret)
{
int Alen=0,Blen=0;
int APlen=0,BPlen=0;//小数部分长度
int Pflag=0,Hflag=0;//默认b大于a
if(*a=='0'||*b=='0'){
(*ret)[0]='0';
(*ret)[1]='/0';
printf("%s/n",*ret);
return ;
}
for(char *p=a;*p!='/0';p++){
if(*p=='.')Pflag=1;
Alen++;
if(Pflag)APlen++;
}
for(p=b,Pflag=0;*p!='/0';p++){
if(*p=='.')Pflag=1;
Blen++;
if(Pflag)BPlen++;
}
if(Alen-APlen>Blen-BPlen||(Alen==Blen)&&a[0]>b[0])//a>b
Hflag=1;
char A=0,B=0,D=0, C=0;//进位标志
int Rlen=0;
int i,j,k,Len=0;
for(i=0;i<Alen+Blen;i++)(*ret)[i]=0;
for(j=Blen-1;j>=0;j--){
A=B=D=0;
if(b[j]!='.'){
B=b[j]-'0';C=0;
for(k=Blen-j-1,i=Alen-1;i>=0;i--){
if(a[i]!='.'){
A=a[i]-'0';
D=A*B+C;
C=((*ret)[k]+D)/10;
char t=(*ret)[k];
(*ret)[k]=((*ret)[k]+D)%10;
t=(*ret)[k];
k++;
if(k>Len)Len=k;
}
}
if(C>0){(*ret)[k++]=C;Len++;}
}
}
(*ret)[Len]='/0';
if(Len<2)(*ret)[0]+='0';
else
for(i=0,j=Len;i<Len/2;i++){//字符串逆序
char temp=(*ret)[i];
(*ret)[i]=(*ret)[--j]+'0';
(*ret)[j]=temp+'0';
}
if(Len>1&&Len%2)(*ret)[(Len+1)/2-1]+='0';
printf("%s/n",*ret);
}
判断一个数是否为平方数
方法:1+3+...+(2n-1),共n个数,求和公式是: ((1+(2n-1)) * n)/2 == n*n
int IsSqrt(int n)
{
int m=0;
if(n<0)return 0;
while(n>0){
n-=2*m+1;
m++;
}
if(n<0)return 0;
else return 1;
}
约瑟夫问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。
有递推公式
f[0]=0;
f[n]=(f[n-1]+m)%n;
int josefus(int n,int m)
{
if(n<=0||m<=0)return 0;
int f=0;
for(int i=1;i<=n;i++)
f=((f-1)+m)%i;
return f+1;//现实中一般从1开始编号
}
打印机1~100中任意10个数的组合的所有情况
unsigned int m=0; //记录组合数
#define Setsize 100 //集合大小
#define Select 2 //组合元素个数
void SearchSet(int *a[],int k)
{
if(k==Select){
for(int i=0;i<Select;i++)printf("%d,",(*a)[i]);
printf("/n");
m++;
}
else{
for(int j=(*a)[k-1];j>1;)
{
(*a)[k]=--j;
SearchSet(a,k+1);
}
}
}
void PrintComposition()
{
int *p=(int *)malloc(sizeof(int)*Select);
for(int i=Setsize;i>0;i--){
p[0]=i;
SearchSet(&p,1);
}
}
//判断系统的字节顺序
#define BigEndian 1
#define LittleEndian 2
int ByteOrder()
{
unsigned int one=1;
return ((*((unsigned char *) &one) == 0) ? BigEndian : LittleEndian);
}