PTA|C语言基础题型(大一上)

目录

关于素数的函数

统计素数并求和 

字符串连接

关于统计单词

回文串的判断

删除重复字符

删除数字字符

删除重复字符

删除指定字符

字符串的逆序输出

求最大值及其下标

 交换最小值和最大值(两个问题分开求)

getchar( )补充知识点:

二维数组的相关问题

数组的边框相加

除了数组的边框相加和(内部数字的和)

每一行(列)的最小值

整体数组的最小值

二维数组偶数和

二维数组左下三角之和

 二维数组的输出方式改变了(看题输出)

 输出矩阵两个对角线上的数(二维数组) 

 矩阵A乘以B(没看懂

矩阵转置

统计字符

两个整数的最大公约数                 (生疏)

求一个正整数的因子之和

 输出小于n的所有水仙花数

关于switch和while的连用

输出完数                ​​​​​​​        ​​​​​​​        ​​​​​​​        (生疏)

Fibonacci 数列(数组实现)

 三角形面积和周长

计算天数(year,month,day)

倒着输出 A 和 B 的乘积。


PTA  函数进阶练习以及字符串练习学习心得:

关于素数的函数

int prime(int x){
    for(int i=2;i

统计素数并求和 

本题要求统计给定整数M和N区间内素数的个数并对它们求和。

输入格式:

输入在一行中给出两个正整数M和N(1≤M≤N≤500)。

输出格式:

在一行中顺序输出M和N区间内素数的个数以及它们的和,数字间以空格分隔。

输入样例:     10      31

输出样例:     7       143

#include
#include
int main() {
	int i, t = 0, k, j;
	int m, n, sum = 0;

	scanf("%d %d", &m, &n);
	if (m == 1)
		m++;//这个需要小心

	for (i = m; i <= n; i++) {
		k = 0;
		for (j = 2; j <=sqrt(i); j++) {//素数的求法
			if (i % j == 0) {
				k = 1;
				break;
			}
		}
		if (k == 0) {//这个要写到第二个for的外面
			sum += i;
			t++;
		}
	}
	printf("%d %d", t, sum);
}

字符串连接

输入样例:hello  world

输出样例:hellloworld

#include
int main()
{
    char to[200],from[100];
    int i,j;
    scanf("%s%s",to,from);
    for(i=0;to[i]!='\0';i++);
    //attention
    for(j=0;from[j]!='\0';j++)
    {
        to[i]=from[j];
        i++;
    }
    to[i]='\0';
    puts(to);
}


关于统计单词

#include
int main()
{
    char c[1000];
    gets(c);
    int n=0,word=0,i,t=0;//n统计所有字符t为统计英语单词个数
    for(i=0;c[i]!='\0';i++)
    { 
        if(c[i]!=' '&&word==0)//没有空格,有字母
        {
            n++;t++;word=1;//t为计数单词的个数,此处有字符
        }
        else if(c[i]!=' '&&word==1)//没有空格,但是为单词中的字母
        {
            n++;//
        }
        else if(c[i]==' '&&word==1)//有空格,但是是单词后面的空格
            word=0;//所以此时变成0
   }
    printf("%d",t);
}

可以在代码中看出,该代码实现了对单词数量(t)的统计以及对字母的统计(n),这个代码考虑的三种情况可以学习,以后还有很多考虑多种情况的题

与下文的统计字符数做对比,上面的要难一些,下面的比较基础

#include
#include
int main()
{
    char c[10000];
    gets(c);
    int i,digit=0,letter=0,space=0,other=0;
    for(i=0;i='0'&&c[i]<='9')
            digit++;
         else if((c[i]>='A'&&c[i]<='Z')||(c[i]>='a'&&c[i]<'z'))
            letter++;
         else if(c[i]==' '||c[i]=='\n')
            space++;
         else other++;
               }
    printf("letter=%d\nspace=%d\ndigit=%d\nother=%d\n",letter,space,digit,other);
}

回文串的判断

输入一个字符串,判断该字符串是否为回文,只考虑数字和字母字符,字母的大小写没有区别。回文就是字符串中心对称,从左向右读和从右向左读的内容是一样的。

若该串字符是回文串输出“yes",否则输出“no”。

感觉这个地方和栈(括号问题)有点相似,但是括号是成对出现的

这里需要从左开始和右开始遍历,如果不是相等就退出循环,和素数函数的判断有点相似

#include
#include
int main()
{
    char ch[100];
    int i,j;
    scanf("%s",ch);
    for(i=0;i='A'&&ch[i]<='Z')
            ch[i]+=32;//把大写字母换成统一的小写字母
    
    for(i=0,j=strlen(ch)-1;i=j)//考虑到了单双数字母的问题//i==j是因为字符个数对称,但i>j是字符个数是单个
        printf("yes");
    else printf("no");
}

删除重复字符

//删除数字字符 单个单个输出字符,跳过Continue来执行
//删除重复字符 先交换大小(冒泡排序)   再前后两个数不等于同一个输出
//删除指定字符 将数组存放在另外一个数组中,跳过指定值存储

删除数字字符

删除前:a1b2c3
删后:abc

#include
#include
int  main()
{
  char str[500];
  int i;
  gets(str);
  for(i=0;i='0'&&str[i]<='9'))
         continue;
      else
         printf("%c",str[i]);
  }
  str[i]='\0';
} 

删除重复字符

删除前:ad2f3adjfeainzzzv  

删除后:23adefijnvz

#include
#include
int main()
{
	char a[85];
	gets(a);
    int i=0,j=0,len=0;
	len=strlen(a);
    char t;
    for(i=0;ia[j+1])
    		{
    			t=a[j];
    			a[j]=a[j+1];
    			a[j+1]=t;
			}
		}
	}//先排序后后删除
    //冒泡排序
	for(i=0;i

把字符串中的所有字符按从小到大的顺序排序(两个排序一样)

#include
#include
int main()
{
    int i,j,len;
    int t;
    char str[20];
    gets(str);
    len=strlen(str);
    for(i=0;istr[j])//交换大小
            {
                t=str[i];
                str[i]=str[j];
                str[j]=t;
            }
        }
    }
    printf("%s",str);
    return 0;
}

删除指定字符

删除前:abcdcf
删除的字符:c
删除后:abdf

法一
#include
#include
	int main (){
	char a[20],x;
	int i,len,k=0;
	gets(a);
	scanf("%c",&x);
	len=strlen(a);
	for(i=0;i
#include
int main(){
    int i,k;
    char a[200];
    gets(a);
    char n;
    scanf("%c",&n);
    for(i=0,k=0;i

字符串的逆序输出

输入样例:Hello World!

输出样例:!dlroW olleH

 这个题目三种解法:(我个人比较熟悉前两种方法)

1.直接从后面遍历输出

2.两个数组                  一个存逆序后的,一个是原数组

3.一个数组  +一个变量            来个前后互相交换,变量只做中间变量(就像是两数交换一样的解题方式)

直接逆序输出
#include
#include
int main(){
    char a[100];
    gets(a);
    //getchar();
    int i;
    for(i=strlen(a)-1;i>=0;i--){
        printf("%c",a[i]);
    }
    return 0;
}

两个数组
#include
#include
int main(){
    char a[100],b[100];
    gets(a);
    //getchar();
    int i,k;
    for(i=strlen(a)-1,k=0;i>=0;i--,k++){
        b[k]=a[i];
    }
    b[k]='\0';//必须有这个字符串的结束标志,否则就不正确
    //for(k=0;b[k]!='\0';k++)
    //printf("%c",b[k]);
    printf("%s",b);
    return 0;
}

变量加数组
#include
#include
int main(){
    char a[100];
    gets(a);
    //getchar();
    int i;
    char temp;

    for(i=0;i

除了字符串的逆序输出,还有数组的,数组的方法其实是一样的,但是数组的 这个方式还是要知道

逆序存放数组中的数据,并输出指定元素

输入:

6
10 8 1 2 3 4
2

输出:2

#include
int main()
{
    int n,i,m;
    scanf("%d",&n);
    int a[n];
    for(i=0;i

输入为一个以“#”结束的字符:这个在for循环中的表示  for(i=0 ; s[i] != '#' ; i++)


PTA  函数部分练习

关于歌词输出  由于歌词的空格和排版,见下  每段都要   \n    和引号

#include 
int main(){
    printf("============\n"
            " 甜  蜜  蜜\n"
            "============\n"
            "词曲:庄  奴\n"
            "演唱:邓丽君\n"
            "\n"
            "甜蜜蜜\n"
            "你笑得甜蜜蜜\n"
            "好像花儿\n"
            "开在春风里\n"
            "开在春风里\n"
            "\n"
            "在哪里\n"
            "在哪里见过你\n"
            "你的笑容这样熟悉\n"
            "我一时想不起\n"
            "啊……\n"
            "在梦里\n"
            "\n"
            "在哪里\n"
            "在哪里见过你\n"
            "你的笑容这样熟悉\n"
            "我一时想不起\n"
            "啊……\n"
            "在梦里\n");
    return 0;
}

在c语言中使用bool  要加头文件stdbool.h

 等号右边数字占4位、左对齐。   注意这个的表达方式 =%-4d  (有负号哦)


下面的内容就很基础是涉及到数组的,有些注意的点还是要看

求最大值及其下标

输入:                6
                           2 8 10 1 9 10
输出:10 2

若是求最小值方法一样,只是要多写一遍 

#include
int main(){
    int i,n,a[100];
    scanf("%d",&n);
    for(i=0;imax){//这个地方的if判断
            max=a[i];
            t=i;
        }
    }
    printf("%d %d\n",max,t);
}

 交换最小值和最大值(两个问题分开求)

本题要求编写程序,先将输入的一系列整数中的最小值与第一个数交换,然后将最大值与最后一个数交换,最后输出交换后的序列。

注意:题目保证最大和最小值都是唯一的。

输入:        5
                   8 2 5 1 4
输出:        1 2 5 4 8

这个题目很有探讨性,涉及到的东西很多,但还是很基础的

#include 
int main() {
    int i, n, a[11], p;//p是所交换数字的临时保存点
    scanf("%d", &n);

    for (i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    int m = 0, min=a[0];         //最小值
    for (i = 1; i < n; i++) { //得到最小值
        if (a[i] < min) {
            m = i;
            min = a[i];
        }
    }
    p = a[0]; //最小值与第一个数交换
    a[0] = min;
    a[m] = p;//第m=i数与第一个数交换交换
//最小值与第一个数交换完毕

    int j = 0 , max = a[0];      //最大值
    for (i = 1; i < n; i++) { //得到最大值
        if (a[i] > max) {
            j = i;
            max = a[i];
        }
    }
    p = a[n - 1]; //最大值与最后一个数交换
    a[n - 1] = max;
    a[j] = p;//最大值j=i的位置与最后一个数交换。

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

求数组的最大值最小值可以直接这样

 max=min=a[0];
    for(int i=0;ia[i])
            min=a[i];
    }

getchar( )补充知识点:

关于getchar

                EOF:end of file  本质是-1

                getchar只读取一个字符

                 

错误代码
#include
int main(){
    char pssword[20]={0};
    printf("请输入密码");

    scanf("%s",password);//123456\n //这个\n 是存入数据时你不自主打上去的换行

    printf("请确认密码(N/Y)");
    char ch=getchar();

    if(ch='Y') printf("成功");
    else if(ch='N') printf("失败");
    return 0;
}

问题:程序在输入密码后自动结束了。 

首先我们要明白一点   scanf(读到空格就不读取了)和getchar(只读取一个字符)函数都是输入函数,他们读取数据并不是直接从键盘读入,而是在键盘之间的缓冲区读入

PTA|C语言基础题型(大一上)_第1张图片

 在我们输入了密码后加\n将数据给电脑   所以缓冲区中还有\n,则下次getchar先读取缓冲区所以就会导致我们没有输入字母,程序已经结束了。参考思路

解决措施:

解决措施和正确方式
#include
int main(){
    char pssword[20]={0};
    printf("请输入密码");

    scanf("%s",password);
    getchar();//把缓冲区的\n 清除掉

    printf("请确认密码(N/Y)");
    char ch=getchar();

    if(ch='Y') printf("成功");
    else if(ch='N') printf("失败");
    return 0;
}

输入方式的不同,也会造成错误

另一情况
#include
int main(){
    char pssword[20]={0};
    printf("请输入密码");

    scanf("%s",password);//123  456\n  //中间scanf输入有空格
    while(getchar()!='\n'){;}//这个没见过,看上面的参考思路吧
    printf("请确认密码(N/Y)");
    char ch=getchar();

    if(ch='Y') printf("成功");
    else if(ch='N') printf("失败");
    return 0;
}

二维数组的相关问题

数组的边框相加

for(i=0;i

除了数组的边框相加和(内部数字的和)

题目设定为5*5的矩阵  

for(int i=1;i<4;i++){
		for(int j=1;j<4;j++){
			sum+=arr[i][j];//for表示的新方法
		}
	}

每一行(列)的最小值

分析:把每一行的第一个数字设为最小值  min =  a[i][0]

for (i = 0; i < m; i++)
    {
        min = a[i][0];
        for (j = 0; j < n; j++)
        {
            if (min > a[i][j])
                min = a[i][j];
        }
        printf("%d\n",min);

    }

整体数组的最小值

int s=0,k=0,min=a[0][0];
    for(i=0;ia[i][j])
        { 
            min=a[i][j];
               s=i;k=j;
        }
    }

二维数组偶数和

for( i=0;i

二维数组左下三角之和

for( i=0;i=j)
				sum+=a[i][j];
     }

 二维数组的输出方式改变了(看题输出)

输入:3   4

输出: 

   0   1   2   3
   1   2   3   4
   2   3   4   5

#include
int main()
{
	int i,j,m,n,a=0;
	scanf("%d %d",&m,&n);
	for(i=0;i

 输出矩阵两个对角线上的数(二维数组) 

注意有两个对角的输出,

输入:

4
25 36 78 13
12 26 88 93
75 18 22 32
56 44 36 58
输出:

25 26 22 58
56 18 88 13

#include
int main(){
	int n=0;
	scanf("%d",&n);
	int a[100][100]={0};
	int i=0,j=0;
	for(i=0;i=0;i--){
		for(j=n-1;j>=0;j--){
			if(i+j==n-1){
				printf("%d",a[i][j]);
				if(i!=0)printf(" ");
			}
		}
	}//第二个对角
//注意是如何输出的
	printf("\n");
}

 矩阵A乘以B(没看懂)

给定两个矩阵A和B,要求你计算它们的乘积矩阵AB。需要注意的是,只有规模匹配的矩阵才可以相乘。即若A有Ra​行、Ca​列,B有Rb​行、Cb​列,则只有Ca​与Rb​相等时,两个矩阵才能相乘。

输入格式:

输入先后给出两个矩阵A和B。对于每个矩阵,首先在一行中给出其行数R和列数C,随后R行,每行给出C个整数,以1个空格分隔,且行首尾没有多余的空格。输入保证两个矩阵的R和C都是正数,并且所有整数的绝对值不超过100。

输出格式:

若输入的两个矩阵的规模是匹配的,则按照输入的格式输出乘积矩阵AB,否则输出Error: Ca != Rb,其中Ca是A的列数,Rb是B的行数。

输入样例1:

2 3
1 2 3
4 5 6
3 4
7 8 9 0
-1 -2 -3 -4
5 6 7 8

输出样例1:

2 4
20 22 24 16
53 58 63 28

输入样例2:

3 2
38 26
43 -5
0 17
3 2
-11 57
99 68
81 72

输出样例2:

Error: 2 != 3
#include 
int main()
{
    int n,m,x,y;
    scanf("%d %d",&n,&m);
    int a[1000][1000];
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&a[i][j]);
        }
    }
    scanf("%d %d",&x,&y);
    int b[1000][1000];
    for(int i=1;i<=x;i++)
    {
        for(int j=1;j<=y;j++)
        {
            scanf("%d",&b[i][j]);
        }
    }
    
    if(m!=x) printf("Error: %d != %d",m,x);
    else
    {
        printf("%d %d\n",n,y);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=y;j++)
            {
                int s=0;
                for(int k=1;k<=m;k++)
                {
                    s+=a[i][k]*b[k][j];
                }
                printf("%d",s);
                if(j!=y) printf(" ");
            }
        printf("\n");
        }
    }
	
return 0;
}

矩阵转置

将一个3×3矩阵转置(即行和列互换)。

输入:1 2 3 4 5 6 7 8 9 

输出:   1   4   7
              2   5   8
              3   6   9

 使用两个矩阵

#include
int main()
{
    int a[3][3],i,j,k;
    for(i=0;i<3;i++)
        for(j=0;j<3;j++)
          scanf("%d",&a[i][j]);
    int b[3][3];

     for(i=0;i<3;i++)
        for(j=0;j<3;j++)
            b[j][i]=a[i][j];

    for(i=0;i<3;i++){
        for(j=0;j<3;j++){
            printf("%4d",b[i][j]);//由于上面已经转置存储到了b中,这里正常输出即可
        }
        printf("\n");
    }
    return 0;
}

使用一个矩阵(简单)

#include
int main(){
    int i,j;
    int a[3][3],b[3][3];
   for(i=0;i<3;i++)
        for(j=0;j<3;j++)
          scanf("%d",&a[i][j]);

    for(i=0;i<3;i++)
    { 
        for(j=0;j<3;j++)
        {
            printf("%4d",a[j][i]);//只用调换i和j的位置但for循环里面的不变
        }
            printf("\n");
    }
}


统计字符

输入:aZ &
           09 Az

输出:letter = 4, blank = 3, digit = 2, other = 1

这里的getchar能输入字符 数字 空格 换行 可以结合到上面的补充知识点 

for (i = 0; i < 10; i++)
	{
		c = getchar();//注意getchar的使用
		if  (c >= '0' && c <= '9')
			digit++;
		else if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
			letter++;
		else if ((c == ' ')||(c == '\n'))
			blank++;
		else
			other++;
	}

while循环的常见写法   scanf的应用

    scanf("%d",&n);
    while(n>=0)
       { 
          sum=sum+n;
          if(n>=80&&n<90)
              t++;
          j++;
          scanf("%d",&n);
        }

    scanf("%d",&n);
    while((scanf("%d",&n))!=-1)
    

两个整数的最大公约数(生疏)

输入:8,12 

输出:4

分析:两个数共有的约数   先找到较小的数然后从2开始除,使两个数都能为0

#include
int main() {
    int a, b;
    int min,max;
    
    scanf("%d,%d", &a,&b);
    min = a < b ? a : b;
    for (int i = 2;i <= min;i++) {
        if (a%i == 0 && b%i == 0) {
            max = i;
        }
    }
    printf("%d", max);
    return 0;
}


求一个正整数的因子之和

输入:8

输出://第一行输出所有因子(空格分隔),第二行输出因子之和

             1 2 4 
              7

 for(i=1;i

 输出小于n的所有水仙花数

三位水仙花数,即其个位、十位、百位数字的立方和等于该数本身。ps水仙花数是一个三位数,若超过999或没到100都是输入不符合

输入的n是:400

输出:

153
370
371

#include
int main()
{
    int n,a,b,c,s,j=0;
        scanf("%d",&n);
    for(int i=101;i

关于switch和while的连用

while((ch=getchar())!='\n')
{
        switch(ch)
    {
        case ' ':blank++;break;
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            digit++;
            break;//这个统一在这写的

        default:other++ ;
    }
}

 switch的应用格式:case  :(冒号)     ; (分号)  break;(分号)

                                default ;(冒号)  ; (分号)  break;(分号)


输出完数(生疏)

一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如:6的因子为1,2,3,而6=1+2+3,因此6是完数。输入整数n,编程找出2-n(包括n)之内的所有完数,并按下列格式输出其因子:6 its factors are 1 2 3。

输入:  10

输出:6 its factors are 1 2 3 

这个题有一点点难哦 

#include
int main()
{
  int i,j,n,sum,k;
    scanf("%d",&n);
  for(i=6;i<=n;i++)
   {
  	 for(j=1,sum=0;j

Fibonacci 数列(数组实现)

斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……编程用数组实现前n项的各项斐波那契数。

输入:20

输出:1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765

#include
int main()
{
    int n,i;
    scanf("%d",&n);
    int a[n];
    a[0]=1;
    a[1]=1;
    for(i=0;i

 三角形面积和周长

#include
#include//注意头文件
int main()
{
    int a,b,c;
    float s,area,d;
    scanf("%d %d %d",&a,&b,&c);
     if(a+b>c&&a+c>b&&c+b>a||a==b==c)//是三角形
     { 
         d=a+b+c;//周长
        s=(a+b+c)/2.0;
        area=sqrt(s*(s-a)*(s-b)*(s-c)); //面积计算
        printf("area = %.2f; perimeter = %.2f",area,d);
     }
    else printf("These sides do not correspond to a valid triangle");
    return 0;
}

计算天数(year,month,day)

计算闰年平年

能被400整除,也能被4整除,但是不能被100整除

if(year%400==0||year%4==0&&year%100!=0)

计算大月小月

#include
int main()

{
     int year,month,day,sum=0,i;
    scanf("%d/%d/%d",&year,&month,&day);
    if(month==1)                //如果是1月,直接输出day就行
        printf("%d",day);
    else{
        for(i=1;i2)
            sum+=1;
        printf("%d",sum);
    }
}
        

倒着输出 A 和 B 的乘积。

输入:5 7

输出:53

#include
int main()
{
	int n,m,sum=0,b=0;
	scanf("%d%d",&n,&m);
	sum=m*n;
//注意循环内的东西
	while(1)
	{
		b+=sum%10;
		sum/=10;
		if(sum==0) break;
		b*=10;
	}
	printf("%d",b);//注意输出时是一个数(五十三)而不是53
	return 0;
}

你可能感兴趣的:(算法,c++,数据结构)