#jitoa# 【C语言刷题技巧和错误检查】 原创

wx658d1c0a139e2
发布于 2023-12-28 19:34
浏览
0收藏

本博客由金陵科技学院-开放原子开源社陆柏廷编写

在C语言刷题的过程中,最重要的不是代码的敲写,而是思路的形成。随着题目难度的上升,程序的复杂度也越来越高,但其实再复杂的题目也不过是由无数基础题目的思路堆叠而成的。因此,在做基础题时,我们就可以有意识的记住它的思路和方法,甚至以后当作源码直接拿出。

1.【冒泡排序】
题目(1)冒泡排序:
将输入的n个数按从小到大的顺序输出。

代码:

#include <stdio.h>
int main(){
int n,i,j;
int a[100];
int b;

scanf("%d",&n);
for(i=1;i<=n;i++){
   scanf("%d\n",&a[i]);
}
for(i=1;i<=n-1;i++){
   for(j=1;j<=n-1-i;j++){
      if(a[j+1]<a[j]){
	b=a[j];
	a[j]=a[j+1];
	a[j+1]=b;
	    }
	   }
     } 

for(i=1;i<=n;i++){
printf("%d ",a[i]);
}


return 0;
}

题目(2)成绩排序:
给出班里某门课程的成绩单,请你按成绩从高到低对成绩单排序输出,如果有相同分数则名字字典序小的在前。

输入格式:
第一行为n (0 < n < 20),表示班里的学生数目;
接下来的n行,每行为每个学生的名字和他的成绩, 中间用单个空格隔开。名字只包含字母且长度不超过20,成绩为一个不大于100的非负整数。

输出格式:
把成绩单按分数从高到低的顺序进行排序并输出,每行包含名字和分数两项,之间有一个空格。

输入样例:
在这里给出一组输入。例如:

4
Kitty 80
Hanmeimei 90
Joey 92
Tim 28

输出样例:
在这里给出相应的输出。例如:

Joey 92
Hanmeimei 90
Kitty 80
Tim 28

代码:

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

struct student{
    char name[30];
    int score;
};

int main(){
    int n;
    int i,j;
    struct student b;
    struct student a[100];

    scanf("%d\n",&n);

    for(i=1;i<=n;i++){
        scanf("%s %d\n",&a[i].name,&a[i].score);
    }

    for(i=1;i<n;i++){
        for(j=1;j<=n-i;j++){
            if(a[j].score<a[j+1].score){
                b=a[j];
                a[j]=a[j+1];
                a[j+1]=b;
            }else if(a[j].score==a[j+1].score&&strcmp(a[j].name,a[j+1].name)>0){
                b=a[j];
                a[j]=a[j+1];
                a[j+1]=b;
            }
        }
    }

    for(i=1;i<=n;i++){
        if(i!=n){
        printf("%s %d\n",a[i].name,a[i].score);
        }else if(i==n){
        printf("%s %d",a[i].name,a[i].score);
        }
    }


    return 0;
}

本题中要求有相同分数则名字字典序小的在前,正是利用了题目(1)的冒泡排序,只不过题目(2)变成了姓名的大小比较,思路仍然相同。
2.【递归】
题目(1)斐波那契数列:
斐波那契数列的是这样一个数列:1、1、2、3、5、8、13、21、34…,即第一项 f(1) = 1,第二项 f(2) = 1…,第 n 项目为 f(n) = f(n-1) + f(n-2)。求第 n 项的值是多少。

int f(int n){
    // 1.先写递归结束条件
    if(n <= 2){
        return 1;
    }
    // 2.接着写等价关系式
    return f(n-1) + f(n - 2);
}

用递归的关键就是找到通用的公式,方便一次次的往复。
题目(2)输出全排列:
请编写程序输出前n个正整数的全排列(n<10),并通过9个测试用例(即n从1到9)观察n逐步增大时程序的运行时间。

输入格式:
输入给出正整数n(<10)。

输出格式:
输出1到n的全排列。每种排列占一行,数字间无空格。排列的输出顺序为字典序,即序列a1,a2,…an排在序列b1,b2,…,bn之前,如果存在k使a1=b1,…,ak=bk,且ak+1<bk+1.
输入样例:

3

输出样例:

123
132
213
231
312
321

代码:

#include <stdio.h>

int x1[10],x2[10],n;

void quan(int k){
    int i;

    if(k>n){
        for(i=1;i<n;i++){
            printf("%d",x1[i]);
        }
            printf("%d\n",x1[n]);
        return ;
    }else{
        for(i=1;i<=n;i++){
            if(x2[i]==0){
                x1[k]=i;
                x2[i]=1;
                quan(k+1);
                x1[k]=0;
                x2[i]=0;
            }
        }
        return ;
    }

}

int main(){
    scanf("%d",&n);
    quan(1);

    return 0;
}

本题的难度与题目(1)相比上升极大,但大致的思路又很相像,其实还是递归的应用,当我们习惯递归的思维后自然可以完成更高难度的题。建议还可以练习:青蛙跳台阶,汉诺塔。

随着代码长度的增加,这时我们就可以适时引入C++的内容简化代码,用更简便的方法达到同样效果。


写题目的过程中我们更多的时间其实花在找错误上,因此,我再介绍几个写题目是常见的报错与错误的检查方法。
(1)直接提示类
这种只要跟着报错提示就可以改对。
(2)答案错误
去devc++上一步步调试,看看是哪一步出错,再进行相应的改动。调试时可以在程序中多设点中间值输出,方便确定错误的位置。
(3)答案正确,但错误
这种多半是情况没考虑全,可以多试试特殊情况,再重复第二种改法。
(4)莫名其妙运行时错误
大部分情况应该是越界,可以看看设的数组是否太小,又可能是在找寻数据的过程中超出范围了,实在不行可以换种思路做题。
(5)段错误
这是访问了不可访问的内存导致的,这种可以直接重写。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
标签
收藏
回复
举报
回复
    相关推荐