程序设计基础期末备考


前言

注明:本篇文章非原创部分,均已指明出处
该博仅为卑微大学牲程序设计基础期末备考,主要参考PTA习题集、中国大学MOOC、B站以及CSDN文章。若有冒犯,敬请批评指正,不胜感激!


提示:以下是本篇文章正文内容,案例仅供参考

一、一些基础概念

注明:就遇到的问题总结,后续将持续补充

(一)、循环结构

请看VCR➡️三种循环语句的详解和使用

(二)、函数

1、strlen函数

计算的是字符串str的长度,从字符的首地址开始遍历,以 ‘\0’ 为结束标志,然后将计算的长度返回,计算的长度并不包含’\0’。
注意: 当计算长度时,只有遇到’\0’才会停止计算,同时计算的长度不包含’\0’。使用时,应该检查字符数组是否以’\0’为结束标志。

(三)、指针

呃……难评。

二、PTA题目集中存在疑惑的实验

1、IP地址转换

将32位二进制码表示的IP地址转换为十进制格式表示的IP地址输出

#include <stdio.h>
#include<string.h>
#include <math.h>
int main()
{
    char s[40];
        gets(s);
        for(int i=0;i<4;i++)
        {
            int j=0;
            for(int q=0;q<8;q++)
            {
                j+=(s[i*8+q]-'0')*pow(2,8-q-1);
            }
            if(i==0) printf("%d",j);
            else printf(".%d",j);
        }
    return 0;
}

原理:由于IP地址由4个8位字段组成,每个字段的取值范围是0-255。每个字段都可以看作是256进制表示的一个数字。所以,
IP地址 = 第1个字段 * 256^3 + 第2个字段 * 256^2 + 第3个字段 * 256^1 + 第4个字段 * 256^0。

因为IP地址由4段构成,所以要遍历四次(i从3开始),将遍历的次数标识看成指数,通过以上公式,通过math.pow(256, i),得出每个字段所对应的权重。
(例:第一个字段对应的权重是 :256^3)

2、汉诺塔问题

输入汉诺塔圆片的数量,输出移动汉诺塔的步骤
递归思想

#include <stdio.h>
void hanoi(int n, char one, char two, char three );

int main() {
	int m;
	scanf("%d", &m);
	getchar();
	char a, b, c;
	scanf("%c %c %c", &a, &c, &b);
	hanoi(m, a, b, c);
}

void hanoi(int n, char one, char two, char three) {
	if (n == 1)
		printf("1: %c -> %c\n", one, three);
	else {
		hanoi(n - 1, one, three, two);
		printf("%d: %c -> %c\n", n, one, three);
		hanoi(n - 1, two, one, three);
	}
}

3、打印月历

给定年月,打印当月的月历表

#include <stdio.h>
int main()
{
    int year,month;
    scanf("%d %d",&year,&month);
    int n=0;
    for(int y=1;y<year;y++)
    {
        int leap=y%100!=0&&y%4==0||y%400==0;
    n+=leap?366:365;
    }
    int month_days[]={0,31,28,31,30,31,30,31,31,30,31,30,31,};
    for(int m=1;m<month;m++)
        n+=month_days[m];
    int leap_year=year%100!=0&&year%4==0||year%400==0;
    if(month>2&&leap_year)
        n++;
    n++;
    int weekday_1st=n%7;
    int days_of_month=month_days[month];
    if(month==2&&leap_year)
        days_of_month=29;
    printf("Sun Mon Tue Wed Thu Fri Sat\n");
    for(int i=0;i<weekday_1st;i++)
        printf("    ");
    for(int d=1;d<=days_of_month;d++)
    {
        printf("%3d",d);
        if((d+weekday_1st)%7==0)
            printf("\n");
        else if(d<days_of_month)
            printf(" ");
    }
    if((days_of_month+weekday_1st)%7!=0)
        printf("\n"); 
    return 0;
}

只是觉得这道题因吹斯汀!

4、字符串的连接

使用指针方式实现两个字符串的连接(不能使用strcat函数)

#include <stdio.h>

int fun(char *str1,char *str2)
{
    while(*str1)//指向元素为空时跳出循环,即str1指向数组str1的末尾后一位
    {
        str1++;//指针自增,指向下一个元素,指导数组末最后一位
    }
    while(*str2)
    {
        *str1=*str2;//str2数组的最后一后赋于str1数组末尾后一位的空位
        str1++//指针后移
        str2++;
    }
    *str1='\0';//puts遇到'\0'才会停止打印
}

int main()
{
    int fun(char *str1,char *str2);
    char str1[80],str2[80];
    gets(str1);
    gets(str2);
    fun(str1,str2);
    puts(str1);
}

5、实数排序

输入n个实数,使用指针引用的方式将它们按从大到小的顺序排列

#include<stdio.h>

#include<stdlib.h>

double order(double *p, int n,double *k);

int main()
{
    double a[10],b[10];
	int n,i;
	scanf("%d",&n);
	for(i=0;i<n;i++)
    {
		scanf("%lf", &a[i]);
	}
	order(a,n,b);
	for(i=0;i<n;i++) 
    {
		if(i==n-1) 
        {
			printf("%.2lf", b[n-1]);
		}
		else 
        {
			printf("%.2lf ",b[i]);
		}
	}
    printf("\n");
	return 0;
}

double order(double *p,int n,double *k) 
{
	int m=0;
	int i,t;
	for (i=0;i<n;i++)
    {
		for (t=0;t<n;t++) 
        {
			if(*(p+i)<*(p+t))
            {
				m++;
			}
		}
		*(k+m)=*(p+i);
		m=0;
	}
}

其实我悟了。

6、使用函数实现字符串复制

将字符串 t 中从第 m 个字符开始的全部字符复制到字符串 s 再输出

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

void strmcpy(char *s, char *t, int m)
{
	int i, j;
	j = 0;
	for (i = m - 1; t[i] != '\0'; i++)
    {
        s[j++] = t[i];
    }
	s[j] = '\0';
}

void main()
{
    void strmcpy(char* s, char* t, int m);
	char s[10], t[10];
	int m, repeat, n;
	scanf("%d", &repeat);
	getchar();
	for (n = 0; n < repeat; n++)
    {
		gets(t);
		scanf("%d", &m);
		getchar();
		if (strlen(t) < m)
        {
            printf("error input");
        }
		else 
        {
			strmcpy(s, t, m);
			puts(s);
		}
	}
}

7、猴子选大王

猴子选大王

#include <stdio.h>
int main()
{
    int n,a[1000];
    int cnt,i,j,k;
    scanf("%d",&n);
    for(i=0;i<=n;i++)
    {
        a[i]=i;
    }
    cnt=1;
    i=0;
    j=1;
    while(a[i]==0)
    {
        i++;
        if(i>n)
        {
            i=0;
        }
    }
    while(cnt<n)
    {
        if(j==3)
        {
        a[i]=0;
        cnt++;
        }
        j++;
        if(j>3)
        {
            j=1;
        }
        i++;
        if(i>n)
        {
            i=0;
        }
        while(a[i]==0)
        {
            i++;
            if(i>n)
            {
                i=0;
            }
        }
    }
    for(k=0;k<=n;k++)
    {
        if(a[k])
        {
            printf("%d",a[k]);
        }
    }
    return 0;
}

8、出租

为输入的号码生成代码的前两行,arr中的数字按递减顺序给出

引用:能力有限,该题直接搬运感谢chenmoan大大

#include<stdio.h>
#include<string.h>
int main()
{
	int phone[11]; 
	int a[10],b[10]; 
	int i,j=0,k=0;
	memset(a,-1,sizeof(a));
	memset(b,-1,sizeof(b));
	char s[11];
	scanf("%s",s);
	for(i=0;i<11;i++)
	{
		phone[i]=s[i]-'0';
		a[phone[i]]++;
	}
	printf("int[] arr = new int[]{");
	for(i=9;i>=0;i--)
	{
		if(a[i]>=0)
		{
			b[j++]=i;
			k++;
		}
	}
	for(i=0;i<k;i++) 
	{
			printf("%d",b[i]);
			if(i<k-1) printf(","); 
	}
	printf("};\nint[] index = new int[]{");
	for(j=0;j<11;j++)
	{
		for(i=0;i<10;i++)
		{
			if(phone[j]==b[i]) 
			{
				printf("%d",i);
				break;
			}
		}
		if(j<10) printf(",");
		else 	printf("};");
	}
	return 0;
}

9、统计大写字母

输入一串字符,统计其中大写字母A-Z各出现多少次
无厘头,救救孩子吧!

10、检查密码

引用:纯属摆烂,该题参考[感谢薛定谔的糖c大大]
写一个密码合法性检查的小功能

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    int n,i,j,l,s,x,z,flag;
    scanf("%d",&n);
    getchar();
    for(i=0;i<n;i++){
        char aw[100];
        flag=0;
        s=0;
        x=0;
        z=0;
        gets(aw);
        l=strlen(aw);
        if(l<6){
            printf("Your password is tai duan le.\n");
        }
        else{
          for(j=0;j<l;j++){
            if(aw[j]>=65&&aw[j]<=90||aw[j]>=97&&aw[j]<=122||aw[j]>=48&&aw[j]<=57||aw[j]==46){
                if(aw[j]==46) x++;
                if(aw[j]>=48&&aw[j]<=57) s++;
                if(aw[j]>=65&&aw[j]<=90||aw[j]>=97&&aw[j]<=122) z++;
                continue;
            }
            else{
                flag=1;
                printf("Your password is tai luan le.\n");
                break;
            }
          }
           if(flag==0){
                if(s+x==l) printf("Your password needs zi mu.\n");
                else if(z+x==l) printf("Your password needs shu zi.\n");
                else printf("Your password is wan mei.\n");
            }
        }
    }
    return 0;
}

三、传说中的重点考点

1、水仙花数

判断一个三位数是否为水仙花数

选择结构

#include <stdio.h>

int main()
{
    int N;
    scanf("%d",&N);
    int a,b,c;
    a=N/100;
    b=(N%100)/10;
    c=N%10;
    if(N>=100&&N<=999)
    {
        if(N==a*a*a+b*b*b+c*c*c)
        {
            printf("Yes");
        }
        else
        {
            printf("No");
        }
    }
    else
    {
        printf("Invalid Value.");
    }
    return 0;
}

按递增顺序输出所有N位水仙花数,每个数字占一行

循环结构

#include <stdio.h>

int pow(int x, int n) {
	int sum = 1;
	for ( int i = 0; i < n; i++ ) {
		sum *= x;
	}
	return sum;
}

int main() {
	int n, sum;
	scanf("%d", &n);
	int max = pow(10, n), min = pow(10, n - 1);
	while ((min++) < max) {
		sum = 0;
		for (int j = min; j != 0; j *= 0.1)
			sum += pow((j % 10), n);
		if (sum == min)
			printf("%d\n", min);
	}
	return 0;
}

2、素数

注:非有效代码,只可意会不可言传

暴力法

遍历的所有大于 1 且小于 n 的整数,判断 n 是否可以被这些数整除,如果不存在可以整除的数,则为素数;否则为合数。

    for (int i = 2; i < n; ++i)
    {
        if (n % i == 0)
        { 
            return 0;
        }
    }
    return 1;

试除法

遍历从 1 到 √n 的所有整数。如果 n 有一个大于 √n 的约数 d,那么必定存在一个小于或等于 √n 的约数 n/d。

    for (int i = 2; i <= n / i; ++i)
    {
        if (n % i == 0)
        {
            return 0;
        }
    }
    return 1;

以i=n/i形式开方,可以提高运行速度。

埃氏筛

基本思路:给定要筛数值的范围 n ,从2开始,将每个素数的倍数标记成合数。如果一个数没有被之前的数标记,那它一定是素数。

欧拉筛

沿用埃氏筛的思路,但不再只筛除素数的倍数,合数的倍数也会进行标记。

bushi ~ 这两种方法品品就得了。

统计素数并求和

循环结构

#include <stdio.h>
int main()
{
    int count=0,sum=0;
    int M,i,N;
    scanf("%d %d",&M,&N);
    for(M;M<=N;M++)
    {
        for(i=2;i<M;i++)
        {
           if(M%i==0)
              break;
        }
        if(M!=1&&i==M)
        {
            count++,sum=sum+M;
        }
    }
    printf("%d %d",count,sum);
    return 0;
}
判断一个给定的正整数是否素数

函数

#include <stdio.h>
#include <math.h>
int A(int n)
{
    int j;
    int judge=1;
    if(n==1) judge=0;
    else{
        for(j=2;j<=sqrt(n);j++){
            if(n%j==0){
                judge=0;
                break;
            }
        }
    }
    return judge;
}

int main()
{
    int N,n;
    scanf("%d",&N);
    for(int i=0;i<N;i++)
    {
        scanf("%d",&n);
        if(A(n))
        {
            printf("Yes\n");
        }
        else
        {
            printf("No\n");
        }
    }
    return 0;
}

3、斐波那契数列

兔子繁衍问题

循环结构

#include <stdio.h>

int f(int n) {
	if (n == 1 || n == 2)
		return 1;
	else
		return f(n - 1) + f(n - 2);
}

int main() {
	int n, month;
	scanf("%d", &n);
	for (month = 1; f(month) < n; month++);
	printf("%d", month);
	return 0;
}

计算斐波那契数列第n项的值

函数

#include <stdio.h>
double fun(int n)
{
    double a[61];
    int i;
    a[1]=1;a[2]=1;
    for(i=3;i<=n;i++)
        a[i]=a[i-1]+a[i-2];
    return a[n];
}
int main()
{
    int n;
    scanf("%d",&n);
    printf("%.0f\n",fun(n));
    return 0;
}

4、最大公约数和最小公倍数

求两个给定正整数的最大公约数和最小公倍数

循环结构

#include <stdio.h>
int main()
{
    int M,N,Max,Min;
    int a,b,c;
    scanf("%d %d",&M,&N);
    a=M;
    b=N;
    while(c=M%N,c!=0)
    {
         M=N;
         N=c;
    }
    printf("%d %d",Max=N,Min=a/N*b);
    return 0;
}

四、去年考题编程部分

保命!:以下题解为白痴思考模式,代码纯纯人工手打,不可参考

1、统计单词数量

题目1

#include <stdio.h>
#include <ctype.h>
int main()
{
	char ch;
	int flag=1;
	int cnt=0;
	while((ch=getchar())&&ch!='\n')
	{
		if((isalpha(ch))&&flag)
		{	
			flag=0;
			cnt++;
		}
		else if(!(isalpha(ch)))
		{
			flag=1;
		}
	}
	printf("%d",cnt);
}

isalpha字母判断函数
头文件:ctype.h
功能:判断字符是否是字母类的(alphabetic),包括:a(ASCII值:97)-z(122) 和 A(65)-Z(90) 。
不是字母类的,返回值0;是字母类的,返回非0值。

2、输入正整数m,判断m是否是素数

注意: 1不是素数,记得单独讨论。

3、水仙花数求和

题目3

#include <stdio.h>
int main()
{
    int N;
    int a,b,c;
    int i,sum;
    scanf("%d",&N);
    for(i=100,i<100;i++)
    {
        a=i%10;
        b=i/10%10;
        c=i/100;
        if(a*a*a+b*b*b+c*c*c==i)
        {
            sum+=i;
        }
    }
    printf("%d",sum);
    return 0;
}

其实这道题也可以只在脑子里过一遍滴~

4、排序

关于冒泡排序和选择排序
题目4
方法一:选择排序

#include <stdio.h>
int main()
{
	int N;
	int i,j,t;
	int a[100];
	scanf("%d",&N);
	for(i=0;i<N;i++)
	{
		scanf("%d",&a[i]);
	}
	for(i=0;i<N;i++)
	{
		for(j=0;j<N;j++)
		{
			if(a[i]>a[j])
			{
				t=a[i];
				a[i]=a[j];
				a[j]=t;
			}
		}
	}
	for(i=0;i<N-1;i++)
	{
		printf("%d",a[i]);
	}
    printf("%d\n",a[N-1]);
    return 0;
}

方法二:冒泡排序

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int N;
    int i,j,t;
    int a[100];
    scanf("%d",&N);
    for(i=0;i<N;i++)
    {
    	scanf("%d",&a[i]);
    }
    for(i=1;i<N;i++)
    {
        for(j=0;j<=N-i-1;j++)
        {
            if(a[j]>a[j+1])
            {
                t=a[j];
                a[j]=a[j+1];
                a[j+1]=t;
            }
        }
    }
    for(i=0;i<N-1;i++)
    {
    	printf("%d",a[i]);
    
    }
    printf("%d\n",a[N-1]);
    return 0;
}

5、逆序整数

题目5

#include <stdio.h>
#include <stdbool.h>
#include <math.h>

int main()
{
	int n,i;
	char a[200]={0},b[200]={0};
	scanf("%d\n",&n);
	scanf("%s\n%s\n"),&a,&b);
	bool flag=true;
	for(i=0;i<n;i++)
	{
		if(a[i]!=b[n-1-i])
		{
			flag=false;
			break;
		}
	}
	if(flag)
	{
		printf("%s and %s are reverse."a,b);
	}
	else
	{
		printf("%s and %s are not reverse."a,b);
	}
	return 0;

6、求圆的周长和面积

so easy!妈妈再也不用担心我的学习了!
所有题都按这个标准来,OK?

7、字符统计

题目7

#include <stdio.h>
int main()
{
    int cnt[255]={0};
    char str[500];
    int i;
    gets(str);
    for(i=0;str[i]!='\0';++i)
        cnt[str[i]]++;
    for(i=0;i<255;i++)
        if(cnt[i]!=0)
           printf("%c:%d\n",i,cnt[i]);
    return 0;
}

8、两数之差的绝对值

题目8

#include <stdio.h>
int main()
{
	int T,i;
	int a[100],b[100],c[100];
	scanf("%d",&T);
	for(i=0;i<T;i++)
	{
		scanf("%d %d",&a[i],&b[i]);
	}
	for(i=0;i<T;i++)
	{
    	if(a[i]>=b[i])
    	{
    		c[i]=(a[i]-b[i]);
    	}
    	else
    	{
    		c[i]=(b[i]=a[i]);
    	}
    	printf("%d\n",c[i]);
    }
   	return 0;
}

9、统计各个数据个数

题目9

EOF在C标准函数库中表示文件结束符(end of file)。在while循环中以EOF作为文件结束标志。

当上面的程序运行时,如果不加" != EOF",那么这个程序就是个死循环,会一直运行下去;加上" != EOF"后该程序就不是死循环了,如果在终端不进行输入该程序会自动结束(while的意思就是说当当前输入缓存还有东西时就一直读取,直到输入缓存中的内容为空时停止)。

10、统计单词

题目10

#include <stdio.h>
#include <string.h>
int main()
{
	char a[10000];
	gets(a);
	int i,word;
	int len=strlen(a);
	for(i=1;i<len;i++)
	{
		if(a[i]==' '&&a[i-1]!=' ')
		{
			word++;
		}
	}
	if(a[len-1]!=' ')
	{
		word++;
	}
	printf("%d",word);
	return 0;
}

11、统计字符个数

题目11

#include <stdio.h>
int main()
{
	char c;
	int letter,space,digit,other;
	while((c=getchar())!='\n')
	{
		if((c>='a'&&c<='z')||c>='A'&&c<='Z')
		{
			letter++;
		}
		else if(c==' ')
		{
			space++;
		}
		else if(c>='0'&&c<='9')
		{
			digit++;
		}
		else
		{
			other++;
		}
	}
	printf("letter=%d\nspace=%d\ndigit=%d\nother=%d\n",letter,space,digit,other);	
	return 0;
}

12、排序

题目12

13、字符串比较

题目13
别问,我也不知道14题离家出走到哪里了。

15、两数的排序

题目15

#include <stdio.h>

void Sort(int *x,int *y);
{
	int temp;
	if(*x>*y)
	{
		temp=*x;
		*x=*y;
		*y=temp;
	}
	printf("After sort:%d %d",*x,*y);
}

void Sort(int *pa,int *pb);
int main()
{
	int a,b;
	scanf("%d %d",&a,&b);
	Sort(&a,&b);
	return 0;
}

16、无符号整数的内部结构

题目16

#include <stdio.h>
int main()
{
	unsinged int v;
	scanf("%u",&v);
	printf("%x\n",v);
	unsinged char *p=(unsinged char*)&v;
	for(int i=0;i<4;i++)
	{
		printf("%x",p[i]);
		if(i!=3)
		{
			printf(" ");
		}
	}
	return 0;
}

unsinged表示无符号数,当定义一个数值型字段中添加该约束,表示该字段的数据没有符号,可以变相增加长度。

17、输出不重复的数组元素

题目17

#include <stdio.h>
int main()
{
	int n,a[20];
	int i,j;
	for(i=0;i<n;&a[i])
	{
		scanf("%d",&a[i]);
	}
	if(n>=1)
	{
		printf("%d",a[0]);
	}
	for(i=1;i<n;i++)
	{
		for(j=0;j<i;j++)
		{
			if(a[i]==a[j])
			{
				break;
			}
		}
		if(j==i)//双重遍历只输出下标相同的
		   {
			printf(" %d",a[i]);
		   }
	}
	return 0;
}

18、求出1到n之间所有奇数的阶乘值

题目18

#include <stdio.h>
int main()
{
    int n;
    int i = 0,j = 1;
    scanf("%d",&n);
    for (i = 1; i <= n;i++) 
    {
        int k = 1;
        if (i % 2 != 0)
        {
            for (j = 1; j <= i; j++) 
            {
                k = k * j;
            }
            printf("%d! = %d\n", i, k);
        }
    }
    return 0;
}

19、求长方体的体积

题目19

#include <stdio.h>
double V(double l,double w,double h)
{
    double V;
    V=l*w*h;
    return V;
}
void main( )
{
	double l,w,h;
	double V;
	scanf("%f %f %f",&l,&w,&h);
	printf("%.2lf",V(l,w,h));
	return 0;
}

20、求1!+2!+……+ n!

仅简单计算阶乘和

#include<stdio.h>
int main()
{
    int N,S=0,T=1;
    scanf("%d",&N);
    for(int i=1;i<=N;i++)
    {
       T*=i;
       S+=T;
    }
    printf("%d",S);
    return 0;
}

题目20

#include <stdio.h>
 
long fact(int n)
{
	if(n<0)
		return 0;
	else if(n==0||n==1)
		return 1;
	else
		return n*fact(n-1);
}

int main(void)
{    
    int i, n;
    double sum; 
    scanf("%d", &n);
    sum = 0;
    for(i = 1; i <= n; i++){
        sum = sum + fact(i); 
     }
     printf("%.0f\n", sum);
 
    return 0;
}

21、斐波那契数列

题目21

#include <stdio.h>

int fib(int n) 
{
    if (n == 1 || n == 2)
       return 1;
    if (n >= 3) 
    return fib(n - 1) + fib(n - 2);
}
 
int main(void) 
{
    int n;
    scanf("%d",&n);
    printf("%d",fib(n));
    return 0;
}

总结

在此特别感谢LRT大美女!姐,你,是我唯一的神!
虽然review和preview只有个p的区别,但是真正的大学牲敢于直面崭新的课本,加油鸭!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

甘一十

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

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

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

打赏作者

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

抵扣说明:

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

余额充值