算法编程题总结 C/C++

目录

一、字符串左旋 (两种实现方法) 

For example

Solution 1

Solution 2

二、杨氏矩阵中查找指定数字 (两种方式) 

限制条件

Solution 1

Solution 2

运行结果

 三、判断是否是自幂数 

自幂数介绍

代码思路

Solution

四、求最小公倍数 (三种求法) 

Solution 1

Solution 2

Solution 3

五、顺序输出每位数 (递归)

六、交换两数的值不增设第三变量(两种方法)

Solution 1

Solution 2

七、求第n个斐波那契数(两种方法)

斐波那契数介绍

Solution 1

Solution 2

注意事项


一、字符串左旋 (两种实现方法) 

实现一个函数,可以左旋字符串中的 k个字符

For example

ABCD 左旋一个字符得到 BCDA

ABCD 左旋两个字符得到 CDAB

Solution 1

#include <stdio.h>
#include <string.h>
#define MAX 10

void str_rotate(char* str,int k)
{
    int i=0;
    int n=strlen(str); 
    for(i=0;i<k;i++)
    {
        //每次旋转一个字符
        char tmp=*str;
        //把后边的n-1个字符往前移
        //把tmp放在最后 
        int j=0;
        for(j=0;j<n-1;j++)
        {
            *(str+j)=*(str+j+1);
        }
        *(str+n-1)=tmp;
     }
}


int main()
{
    char arr[MAX]="";
    gets(arr);//输入字符 
    int k=0;//旋转k个字符
    scanf("%d",&k); 
    str_rotate(arr,k);
    printf("%s\n",arr);
    return 0; 
 } 

Solution 2

例如

ABCDEF

左旋两个,则把前两个当成一体,进行翻转

AB CDEF

BA FEDC ,翻转

再整体翻转

变成CDEFAB

 #include <stdio.h>
 #include <assert.h>
 #include <string.h>
 
 #define MAX 10
 
 void reverse(char* left,char* right)//翻转需要知道前后地址 
 {
     assert(left);
     assert(right);
     while(left<right)
     {
          char tmp=*left;
         *left=*right;
         *right=tmp;
         left++;
         right--;
    }
    
 }
 
 
 void str_rotate(char* str,int k)
 {
     assert(str);
     int n=strlen(str);
     reverse(str,str+k-1);//左边翻转 
     reverse(str+k,str+n-1);//右边翻转 
     reverse(str,str+n-1);//整体翻转 
 }
 
 
 int main()
{
    char arr[MAX]="";
    gets(arr);//输入字符 
    int k=0;//旋转k个字符
    scanf("%d",&k); 
    
    str_rotate(arr,k);
    
    printf("%s\n",arr);
    return 0; 
 }  

二、杨氏矩阵中查找指定数字 (两种方式) 

有一个数组矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的

在这样的矩阵中查找每个数字是否存在

such as:

1 2 3

4 5 6

7 8 9

限制条件

要求时间复杂度小于 O(N)

Solution 1

#include <stdio.h>

#define ROW 3
#define LINE 3 

int find_num(int arr[ROW][LINE],int r,int c,int k)
{
    //先找右上角的数字,然后比较,大的话就往下移,小的话就往左移 
    int x=0;
    int y=c-1;
    
    while(x<r&&y>=0)
    {
        if(arr[x][y]<k)
        {
            x++;//往下移 
        }
        else if(arr[x][y]>k)
        {
            y--;//往左移 
        }
        else
        {
            printf("%d %d\n",x,y);
            return 1;//相等,找到了 
        }
    }
    return 0;
    
 } 



int main()
{
    int arr[ROW][LINE]={0};
    printf("请输入杨氏矩阵:\n");  
    int i=0;
    int j=0;
    for(i=0;i<ROW;i++)
    {
        for(j=0;j<LINE;j++)
        {
            scanf("%d",&arr[i][j]);
        }
    }
    printf("请输入你要查找的数字:\n");
    int k=0;//查找的数字k
    scanf("%d",&k); 
    int x=ROW;//行数 
    int y=LINE;//列数 
    int ret=find_num(arr,ROW,LINE,k);
    
    if(ret==1)
    {
        printf("找到了\n");
    }
    else
    {
        printf("找不到\n");
    }
    return 0;
}

Solution 2

#include <stdio.h>

#define ROW 3
#define LINE 3 

int find_num(int arr[ROW][LINE],int* px,int* py,int k)
{
    int x=0;
    int y=*py-1;//*py,列数解引用 
    while(x<*px&&y>=0)
    {
        if(arr[x][y]<k)
        {
            x++;
        }
        if(arr[x][y]>k)
        {
            y--;
        }
        if(arr[x][y]==k)
        {
            *px=x;
            *py=y;
            return 1;
        }
    }
    return 0;
}


int main()
{
    int arr[ROW][LINE]={0};
    printf("请输入杨氏矩阵:\n");  
    int i=0;
    int j=0;
    for(i=0;i<ROW;i++)
    {
        for(j=0;j<LINE;j++)
        {
            scanf("%d",&arr[i][j]);
        }
    }
    printf("请输入你要查找的数字:\n");
    int k=0;//查找的数字k
    scanf("%d",&k); 
    int x=ROW;//行数 
    int y=LINE;//列数 
    int ret=find_num(arr,&x,&y,k);
    
    if(ret==1)
    {
        printf("找到了\n");
        printf("下标是%d %d\n",x,y);
    }
    else if(ret==0)
    {
        printf("找不到\n");
    }
    return 0;
}

运行结果

 三、判断是否是自幂数 

自幂数介绍

类似于水仙花数,只不过位数可以不是3位数

假设位数为n

每位数的n次方之和,等于该数

代码思路

(1)先判断位数n

(2)再计算每一位的n次方之和

(3)判断

Solution

#include <stdio.h>
#include <math.h>
int main()
{
    int a=0;
    scanf("%d",&a);
    int n=1;//最起码是一位数 
    int tmp=a;//先保存下a的值,方便后续判断 
    while(a/10)
    {
        n++;
        a=a/10;
    }
    a=tmp;//让a进行下一步计算
    int sum=0;
    while(a)
    {
        sum+=pow(a%10,n);
        a=a/10;
     } 
     //判断 
    if(sum==tmp)
    {
        printf("%d是自幂数",tmp);
    }
    else
    {
        printf("%d不是自幂数",tmp);
    }
    
    return 0;
}

四、求最小公倍数 (三种求法) 

Solution 1

#include <stdio.h>

int main()
{
    int a=0;
    int b=0;
    scanf("%d %d",&a,&b);
    int m=a>b?a:b;//m为最小公倍数,先让m取两者较大的数
    while(1)
    {
        if(m%a==0&&m%b==0)
        {
            printf("%d\n",m);
            break;
        }
        m++;
     } 
    return 0;
}

Solution 2

#include <stdio.h>

int main()
{
    int a=0;
    int b=0;
    scanf("%d %d",&a,&b);
    int i=0;
    for(i=0;;i++)
    {
        if(a*i%b==0)
        {
            printf("%d\n",a*i);
            break;
        }
    }
    return 0;
}

Solution 3

辗转相除法,先算出来最大公约数n,再算最小公倍数(a*b)/n

五、顺序输出每位数 (递归)

#include <stdio.h>

void print(unsigned int n)
{
    if (n > 9)
    {
        print(n / 10);
    }
    printf("%d\n", n % 10);
}

int main()
{
    unsigned int num = 0;
    scanf("%u", &num);
    //递归 
    print(num);//自定义print函数,打印数字的每一位 
    return 0;
}

六、交换两数的值不增设第三变量(两种方法)

Solution 1

设计思路

    a=a+b;
    b=a-b;//a-b得到的是交换前a的值,将其赋给b
    a=a-b;//等式右边的a,值为第一个等式左边的a,即交换前的a与b之和;
          //等式右边的b的值为交换前的a,(交换前a+交换前b)-交换前a = 交换前的b

代码内容

#include <stdio.h>

int main()
{
    int a,b;
    scanf("%d %d",&a,&b);
    printf("交换前:a = %d  b = %d\n",a,b);
    a=a+b;
    b=a-b;
    a=a-b;
    printf("交换后:a = %d  b = %d\n",a,b);
    return 0;
 } 

注意事项

如果数字过大,将失效


Solution 2

设计思路

 a=a^b;//异或一下
 b=a^b;
 a=a^b; 

代码内容

#include <stdio.h>

int main()
{
    int a,b;
    scanf("%d %d",&a,&b);
    printf("交换前:a = %d  b = %d\n",a,b);
     a=a^b;
     b=a^b;
     a=a^b; 
    printf("交换后:a = %d  b = %d\n",a,b);
    return 0;
 } 

数字再大,也可以正确算出结果

七、求第n个斐波那契数(两种方法)

斐波那契数介绍

1 1 2 3 5 8 13 21 34 55

后一项等于前两项之和


Solution 1

递归的方式,简单明了

但递归层数太深,将变得不再适用

#include <stdio.h>

int Fib(int n)
{
    if(n<=2)
        return 1;
    else
        return Fib(n-1)+Fib(n-2);
}

int main()
{
    int n=0;
    scanf("%d",&n);
    int ret=Fib(n);
    printf("%d\n",ret);
    return 0;
}

Solution 2

采用循环的办法,无论多少层都能快速计算出结果

#include <stdio.h>

int Fib(int n)
{
    int a=1;
    int b=1;
    int c=0;
    while(n>2)
    {
        c=a+b;
        a=b;
        b=c;
        n--;
    }
}

int main()
{
    int n=0;
    scanf("%d",&n);
    int ret =Fib(n);
    printf("%d\n",ret);
    return 0;
}

注意事项

本程序适用于计算第47位之前的斐波那契数,第47位之后将计算出负数

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摸鱼哥myg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值