嵌入式C语言常用36种基础算法题,实力进阶必备(全网最全、高质量)(一)

8 篇文章 0 订阅
6 篇文章 0 订阅

1.输入一个整数,判断它是不是回文数?

        首先我们要知道什么是回文数,回文数是正序和逆序相等的数,比如数字12321,正序是12321,逆序也是12321,因此12321是逆序数。注意:逆序数可以是任意位的整数。

 参考代码一:

#include <stdio.h>
#include <string.h>

int main(void) {
    
    char str[100];

    printf("请输入一个整数吧\n");
    fgets(str, sizeof(str), stdin);

    int count = strlen(str) - 1; // 减1是为了忽略换行符
    
    int i;
    for (i = 0; i < count / 2; i++) {
        if (str[i] != str[count - 1 - i]) {
            printf("不是回文数: %s", str);
            break;
        }
    }
    
    if (i == count / 2) {
        printf("是回文数");
    }

    return 0;
}

 参考代码二:

#include<stdio.h>
#include<string.h>

void test(char *str, int count);

void test(char *str, int count) {
    char *start = str;
    char *end = str + count -1; // 计算出尾地址
    // printf("首地址:%p 尾地址:%p",start,end);
    
    // 两边同时取值,i计次数只用一半: count/2
    int i = 0;
    for ( i = 0; i < count/2; i++) {
        if(*start != *end) {
            printf("这是不是回文数");
            break;
        }
        start++; // 这里是++
        end--;  // 这里是--  1加1减,两边向中间靠
    }

    if(i == count/2) {
        printf("这是回文数");
    }
}

int main(void) {

    char str[100];

    printf("请输入一个整数吧\n");
    fgets(str, sizeof(str), stdin);
    int count = strlen(str) - 1; // 减1是为了忽略换行符
    test(str,count);
    
    return 0;
}

 第二种方法,是在第一种代码方法的基础进行了稍微的改进,本质上是一样的逻辑,第二种稍微使用了一点数组指针,有利于学习指针。 

基本实现方法:         

        数字字符串,使用for循环从数字左右边,各取一个字符比较,如果有不一样的,这个数字就不是回文数,比较完了都一样,说明是回文数。

部分代码说明:

        1. fgets()是一个输入函数,用于从标准输入(通常是键盘)读取一行字符,并将其存储到指定的字符串数组中。

        2.stdin 表示标准输入流,这里是指键盘输入

代码运行结果:


2.求所有的水仙花数 

        水仙花数:一个三位数的整数,各个位数的立方相加等于这个数。

        例如:153 = 1*1*1 + 5*5*5 + 3*3*3

        水仙花数因为是三位数,所有取值范围是100 - 999之间。

 参考代码:

#include<stdio.h>

int main(void) {
    
    for (int i = 100; i <= 999; i++) {
        int a = i/100;
        int b = i/10%10;  
        int c = i%10;

        if(a*a*a + b*b*b + c*c*c == i) {
            printf("水仙花数:%d\n",i);
        }
    }
    
    return 0;
}

 基本实现方法:

        使用for循环,i从100递增对999,循环的过程中,对每一个i分别取出百位、十位、个位。然后它们的立方相加,如果等于i的值,则这个数就是水仙花数。

代码部分说明:

代码运行结果:


3.输入两个数,求最大公约数,最小公倍数。

        例如,求28和42的最大公倍数和最小公约数。

参考代码:

#include <stdio.h>

// 求最大公约数
int test(int a, int b) {
    if(a % b != 0) { 
        test(b,a % b);
    }else{
        return b;
    }
}

int main() {
    int a , b , c;
    printf("请输入两个整数:");
    scanf("%d %d",&a,&b);
    
    if(a > b) {
        c = test(a, b);  
    }else{
        c = test(b,a);
    }
    printf("最大公约数:%d\n",c);
    printf("最小公倍数:%d\n",(a/c) * (b/c) * c); 
    return 0;
}

 基本实现方法:

        其实这题并不难,主要是使用辗转相除法来计算,这里使用了递归函数来写的,稍微有一点废脑。以下是辗转相除法的计算过程:

 部分代码说明:

        test()函数是自定义的一个递归函数,用于计算最大公约数的。递归函数可以简单的理解为:自己调用自己的函数,若满足结束条件后就回自行结束调用。

代码运行结果:


4.有1、2、3、4个数字,能组成多少个互不相同而且无重复数字的三位数?都是多少?

        这题难度较低,主要是考验基础数学和编程逻辑思维。

参考代码:

#include<stdio.h>

int main(void) {
    
    int num[4] ={1,2,3,4};
    int p = 0; // 组成的不重复不相同整数 数量

    for (int i = 0; i < 4; i++) {
        int a = num[i];
        for (int j = 0; j < 4; j++) {
            int b = num[j];
            if(b != a) { // 限制条件: 防止出现数字重复
                for (int k = 0; k < 4; k++) {
                    int c = num[k];
                    if(c != a && c != b) { // 限制条件: 防止出现数字重复
                        p++;
                        printf("%d\n",a*100 + b * 10 + c);
                    }
                }
            }
        }
    }
    
    printf("可以组成%d种:",p);

    return 0;
}

 基本实现方法:

        使用for循环取出数组中的整数1、2、3、4,注意不能取重复的数字,然后不断的进行拼凑,最后得到满足的数字。

部分代码说明:

代码运行结果:


5.输入一行字符串,分别统计出英文字母、数字和其他字符的个数。

        难度比较低,重点知道是英文字母、数字、其他字符的ASCII码范围,可以查阅百度相关资料,ASCII码表。

参考代码: 

#include<stdio.h>
#include<string.h>

void test(char *str,int count) {
    char *start = str;
    int a = 0;  // 计算英文字母数量
    int b = 0;  // 计算数字数量
    int c = 0;  // 其他符号数量
    for (int i = 0; i < count; i++) {
        // 小写字母: 97(a) - 122(z)
        if(*start >= 97 && *start <= 122) {
            a++;
        // 大写字母: 65(A) - 90(Z)
        }else if(*start >= 65 && *start <= 90) {
            a++;
        // 数字: 48(0) - 57(9)  十个阿拉伯数字。
        }else if(*start >=48 && *start <= 57) {
            b++;
        // 默认都为其他字符
        }else{
            c++;
        }
       start++;
    }
    printf("英文字母数量:%d\n",a);
    printf("数字数量:%d\n",b);
    printf("其他符号数量:%d\n",c);
}


int main(void) {
    
    char str[100];

    printf("随便输入一个字符串吧\n");
    fgets(str, sizeof(str), stdin);

    int count = strlen(str) -1; // 减掉回车键 1

    test(str,count);
    return 0;
}

 基本实现方法:

         for循环不断读取字符数组中的每一个字符,判断字符的ASCII码,进行计次即可。

部分代码说明:

  fgets()函数可以接受任意内容,包括空格。fgets()函数用于从输入流中读取一行文本,并将其存储在指定的缓冲区中,直到遇到换行符或达到指定的最大字符数(包括空格和其他字符)。因此,无论是标点符号、空格还是其他字符,fgets()函数都可以接收并储存它们。(补充说明)

代码运行结果:


6.求以下数列前n项的和:2/1 + 3/2  + 5/3 + 8/5 + 13/8 + 21/13 + .......。

        这题的关键是总结数字递增的规律,难度较低。大致的规律如下图:

参考代码:

#include<stdio.h>

int main(void) {
    
    int a = 2;
    int b = 1;
    int n = 1;
    int temp = 0;
    float sum = 0;

    printf("请输入一个整数n:");
    scanf("%d",&n);

    for (int i = 0; i < n; i++) {
        sum = sum + (float)a/b;
        temp = b;
        b = a;
        a = (a + temp);
    }
    printf("%f",sum);
    return 0;
}

 基本实现方法:按照数列递增的规律,使用for把它们相加起来。

 部分代码说明:

 代码运行结果:


7.将一个正整数分解因数。例如:输入90,打印出90=2*3*3*5。

        这题难度适中,能比较好的锻炼编程逻辑思维。

参考代码:

#include<stdio.h>

int main(void) {

    unsigned int num = 0;
    printf("请输入一个整数:");
    scanf("%d",&num);
    unsigned int temp = num;
    int sum = 1;
    int i = 2;
    int j = 0;
    printf("%d=",num);
    if(num > 1) {
        while (sum < num) {
            if (temp % i == 0) {
                temp = temp / i;
                sum = sum * i;
                if(j == 0) {
                    printf("%d",i);
                    j = 1;
                }else{
                    printf("*%d",i);
                }
            }else{
                i++;
            }
        }
    }else{
        printf("%d",num);
    }
    return 0;
}

基本实现方法: 我也说不清,略~ ,需要自己去理解理解。

部分代码说明:

代码运行结果:


8.编写程序,将用户输入的字符串中的所有的字符a用*代替,然后输出。

        难度低,主要是ASCII码的判断和数组元素值的替换。

参考代码:

#include <stdio.h>
#include <string.h>

void replace(char *str, int count);

void replace(char *str, int count) {
    char *start = str;
    int i = 0;
    while (i < count) {
        // 小写字母a的ASCII码值是: 97
        if(*start == 97) {
            *start = '*';
        }
        i++;
        start++;
    }
}

int main(void) {
    char str[100];
    printf("请输入字符串: ");
    fgets(str, sizeof(str), stdin);
    
    int count = strlen(str) - 1; // 减掉换行符
    
    replace(str, count);
    
    printf("%s", str);
    
    return 0;
}

基本实现方法:

        使用循环,读取字符串中的每一个字符,根据ASCII码判断,如果是字符a(97),就把当前数组下标的元素值替换修即可。

部分代码说明:

代码运行结果:


9.编写一个程序,将一个一维数组的元素逆序存放并输出。例如,原顺序为1、2、3、4、5,逆序后为  5、4、3、2、1

        这题需要注意的是,只是逆序存放,并不是从小到大排列或者从大到小排列,我们只要按照原来的顺序逆过来就行了。

参考代码:

#include <stdio.h>
#include <string.h>

void test(int *arr, int size) {
    int *start = arr;
    int *end = arr + size - 1;
    int temp = 0;
    // printf("首地址:%p,尾地址:%p",start,end); 
    for (int i = 0; i < size/2; i++) {
       temp = *start;
       *start = *end;
       *end = temp;
       start++;
       end--;
    }   
}

int main(void) {
    
    int arr[] = {1,2,3,4,5};
    
    test(arr, 5);

    for (int i = 0; i < 5; i++) {
        printf("%d",arr[i]);
    }
    return 0;
}

基本实现方法:使用for循环从int数组的两边同时取相应的元素值,然后进行交换,不断的往两边靠拢,最后实现数组的逆序排列。

部分代码说明:

代码运行结果:


10.求3行3列矩阵a[3][3]={1,2,3,4,5,6,7,8,9}非对角线上元素之和。

        这题实际的代码有点降智的感觉,可能是我个人的原因,这题建议自己写。

参考代码:

#include<stdio.h>

/*
*   a11 a12 a13      a[0][0]  a[0][1]  a[0][2]              
*   a21 a22 a23   => a[1][0]  a[1][1]  a[1][2] 
*   a31 a32 a33      a[2][0]  a[2][1]  a[2][2]              
*/

int main(void) {
    int a[3][3] = {
    {1,2,3},
    {4,5,6},
    {7,8,9}};

    int sum = 0;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if(i != j) {
                if((i == 1 && j == 0) || (i == 0 && j == 1)) {
                    sum += a[i][j];
                }else if((i == 2 && j == 1) || (i == 1 && j == 2)) {
                    sum += a[i][j];
                }
            }
        }
    }
    printf("非对角线元素之和:%d",sum);
    return 0;
}

基本实现方法:主打的就是对二维数组进行遍历。

部分代码说明:

代码运行结果:


11.变成判断输入的整数的正负性和奇偶性。如果为正数,输出Z,如果为负数,输出F,如果为偶数,输出O,如果为正数,输出J。 

        这题使用if语句来写就可以了,但是稍微有点封繁琐。

参考代码:

#include<stdio.h>

int main(void) {
    // int 如果未进行声明 ,默认为有符号的。
    int num = 0;
    printf("请输入一个整数:");
    scanf("%d",&num);
    if(num > 0) {
        if(num > 1 && (num % 2) == 0) {
            printf("\nZ O"); // 正数 偶数
        }else if(num > 1 && (num % 3) == 0) {
            printf("\nZ J"); // 整数 奇数
        }else{
            printf("\nZ J"); // 整数 奇数   
        }
    }else if(num < 0){
        if(num < -1 && (num %2) == 0) {
            printf("\nF O"); // 负数 偶数
        }else if(num < -1 && (num %3) == 0) {
            printf("\nF J"); // 负数 奇数
        }else{
            printf("\nF J"); // 负数 奇数
        }
    }else{
        printf("\n0");  // 0
    }
    return 0;
}

基本实现方法:使用多个if反复判断即可。

部分代码说明:

代码运行结果:


12.计算并输出1-200以内不能被5整除的整数之和。

        很简单,可以当成练练手。

参考代码:

#include<stdio.h>

int main(void) {
   
   int sum = 0;
   for (int i = 1; i <= 200; i++) {
        if(i % 5 == 0) {
            sum += i;
        }
   }
    printf("1-200之间能被5整除的数之和为:%d",sum);
    return 0;
}

基本实现方法:

部分代码说明:

代码运行结果:


13,从键盘输入N和A的值,计算a+aa+aaa+aaaa+....+aa...a(n个a)的值。

        这题计算需要一定的技巧,当时我自己第一次写,写了很复杂的方法,其实找到了技巧,也就是几行代码的事情。

参考代码:

#include <stdio.h>

// 从键盘输入n和a的值,计算a+aa+aaa+aaaa+....+aa...a(n个a)的值。
int main(void) {

    int n = 2;
    int a = 2;
    
    printf("请输入a和n:");
    scanf("%d %d",&a,&n);
    
    int m = 1;
    int sum = 0;

    for (int i = 0; i < n; i++) {
        sum = sum + a * m;
        m = m * 10 + 1;
    }

    printf("%d",sum);
}

这里需要注意一点,由于是使用int数据类型,因此n和a的值不能过大,否则m值和sum的值就会超过int类型的范围,造成溢出。

基本实现方法:

部分代码说明:

代码运行结果:


14.输入5个数求他们中的最大值和平均值并输出。

        这一题只是求数组中的最大值和平均值,并不是按大小排列,因此不能改变数组中成员的位置和排序。

参考代码:

#include<stdio.h>

int main(void) {
    
    int num[5];
    int max = 0;
    int sum = 0;

    for (int i = 0; i < 5; i++) {
        scanf("%d",&num[i]);
        if(max < num[i]) {
            max = num[i];
        }
        sum += num[i];
    }
    printf("最大值:%d\n",max);
    printf("平均值:%f",(float)sum / 5);
    return 0;
}

 没有什么技巧,按照通常的方式写即可。

基本实现方法:

部分代码说明:

代码运行结果:


15. 输出所有200-400以内能被3整除且个位数字为6的整数。

        这题比较简单。

参考代码:

#include<stdio.h>

int main(void) {
    
    for (int i = 200; i <= 400; i++) {
       if(i % 3 == 0 && i % 10 == 6) {
            printf("%d\n",i);
       }
    }
    return 0;
}

基本实现方法:

部分代码说明:

代码运行结果:


以上代码仅供参考,创作不易,欢迎点赞+关注!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

百院小韦

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

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

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

打赏作者

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

抵扣说明:

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

余额充值