常用算法

来源:互联网 发布:淘宝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){//交换mn

              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]='-';
    }
}
}

写一个程序,要求功能:求出用125这三个数不同个数组合的和为100的组合个数。

  
x1的个数,y2的个数,z5的个数,number是组合数
注意到0<=x<=1000<=y<=500<=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);
}

 

 


原创粉丝点击