目录

关于素数的函数

统计素数并求和

字符串连接

关于统计单词

回文串的判断

删除重复字符

删除数字字符

删除重复字符

删除指定字符

字符串的逆序输出

求最大值及其下标

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

getchar( )补充知识点:

二维数组的相关问题

数组的边框相加

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

每一行(列)的最小值

整体数组的最小值

二维数组偶数和

二维数组左下三角之和

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

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

矩阵A乘以B(没看懂

矩阵转置

统计字符

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

求一个正整数的因子之和

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

关于switch和while的连用

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

Fibonacci 数列(数组实现)

三角形面积和周长

计算天数(year,month,day)

倒着输出 A 和 B 的乘积。


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

关于素数的函数

int prime(int x){for(int i=2;i<x;i++){if(x%i==0) break;}if(x==i)return 1;//是素数 返回值为1 //这里有两种情况//第1.如2这个数字已经除完后退出2.一直不能被除直到i加到了它本身等于xelse return 0;//不是素数返回0 错误

统计素数并求和

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

输入格式:

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

输出格式:

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

输入样例:10 31

输出样例:7 143

#include#includeint 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

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

关于统计单词

#includeint 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#includeint main(){char c[10000];gets(c);int i,digit=0,letter=0,space=0,other=0;for(i=0;i='0'&&c[i]='A'&&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#includeint 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#includeintmain(){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#includeint main(){char a[85];gets(a);int i=0,j=0,len=0;len=strlen(a);char t;for(i=0;i<len-1;i++){for(j=0;ja[j+1]){t=a[j];a[j]=a[j+1];a[j+1]=t;}}}//先排序后后删除//冒泡排序for(i=0;i<len;i++){if(a[i]!=a[i+1])printf("%c",a[i]);}}

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

#include#includeint main(){int i,j,len;int t;char str[20];gets(str);len=strlen(str);for(i=0;i<len;i++)//双重循环,类似于数字排序{for(j=i+1;jstr[j])//交换大小{t=str[i];str[i]=str[j];str[j]=t;}}}printf("%s",str);return 0;}

删除指定字符

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

法一#include#includeint main (){char a[20],x;int i,len,k=0;gets(a);scanf("%c",&x);len=strlen(a);for(i=0;i<len;i++){if(a[i]!=x){//当相等的时候我们就不进行存储a[k]=a[i];//通过另一个数组存储k++;}}a[k]='\0';//注意存储结尾要加'\0'puts(a);return 0;}法二#include#includeint main(){int i,k;char a[200];gets(a);char n;scanf("%c",&n);for(i=0,k=0;i<strlen(a);i++,k++){if(a[i]==n){//保证相等的跳过a[k]=a[i+1];i++;}else a[k]=a[i];}a[k]='\0';puts(a);return 0;}

字符串的逆序输出

输入样例:Hello World!

输出样例:!dlroW olleH

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

1.直接从后面遍历输出

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

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

直接逆序输出#include#includeint main(){char a[100];gets(a);//getchar();int i;for(i=strlen(a)-1;i>=0;i--){printf("%c",a[i]);}return 0;}两个数组#include#includeint 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#includeint main(){char a[100];gets(a);//getchar();int i;char temp;for(i=0;i<strlen(a)/2;i++){//注意这里i的长度/2temp=a[i];a[i]=a[strlen(a)-i-1];a[strlen(a)-i-1]=temp;}printf("%s",a);return 0;}

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

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

输入:

6
10 8 1 2 3 4
2

输出:2

#includeint main(){int n,i,m;scanf("%d",&n);int a[n];for(i=0;i<n;i++)scanf("%d",&a[i]);int b[n];for (i = 0;i<n;i++){b[n-i-1]=a[i];//需要注意的存储方式}scanf("%d",&m);//输入在逆序存放后的数组对应下标 printf("%d",b[m]);}

输入为一个以“#”结束的字符:这个在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

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

#includeint main(){int i,n,a[100];scanf("%d",&n);for(i=0;i<n;i++){scanf("%d",&a[i]);}int t=0,max=a[0];//注意这里两个都要为0初始化,否则过不了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  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;i<n;i++){ if(maxa[i])min=a[i];}

getchar( )补充知识点:

关于getchar

EOF:end of file 本质是-1

getchar只读取一个字符

错误代码#includeint 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(只读取一个字符)函数都是输入函数,他们读取数据并不是直接从键盘读入,而是在键盘之间的缓冲区读入

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

解决措施:

解决措施和正确方式#includeint 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;}

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

另一情况#includeint main(){char pssword[20]={0};printf("请输入密码");scanf("%s",password);//123456\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<m;i++){ for(j=0;j<n;j++) if(i==0||i==m-1||j==0||j==n-1)d+=a[i][j];}

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

题目设定为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  a[i][j])min = a[i][j];}printf("%d\n",min);}

整体数组的最小值

int s=0,k=0,min=a[0][0];for(i=0;i<m;i++){for(j=0;ja[i][j]){ min=a[i][j]; s=i;k=j;}}

二维数组偶数和

for( i=0;i<m;i++){for( j=0;j<n;j++) {if(a[i][j]%2==0)s=s+a[i][j]; }}

二维数组左下三角之和

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

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

输入:3 4

输出:

0123
1234
2345

#includeint main(){int i,j,m,n,a=0;scanf("%d %d",&m,&n);for(i=0;i<m;i++){for(j=0;j<n;j++){printf("%4d",a++);if(j==n-1)printf("\n");}a=i+1;//注意}return 0;}

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

注意有两个对角的输出,

输入:

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

#includeint main(){int n=0;scanf("%d",&n);int a[100][100]={0};int i=0,j=0;for(i=0;i<n;i++){for(j=0;j<n;j++){scanf("%d",&a[i][j]);}}for(i=0;i<n;i++){for(j=0;j=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 31 2 34 5 63 47 8 9 0-1 -2 -3 -45 6 7 8

输出样例1:

2 420 22 24 1653 58 63 28

输入样例2:

3 238 2643 -50 173 2-11 5799 6881 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

输出: 147
258
369

使用两个矩阵

#includeint 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;}

使用一个矩阵(简单)

#includeint 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 = '0' && c = 'A' && c = 'a' && c <= 'z'))letter++;else if ((c == ' ')||(c == '\n'))blank++;elseother++;}

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

#includeint main() {int a, b;int min,max;scanf("%d,%d", &a,&b);min = a 


求一个正整数的因子之和

输入:8

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

1 2 4
7

 for(i=1;i<n;i++) if(n%i==0){printf("%d ",i);sum=sum+i;}printf("\n");printf("%d",sum);

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

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

输入的n是:400

输出:

153
370
371

#includeint main(){int n,a,b,c,s,j=0;scanf("%d",&n);for(int i=101;i<n;i++){a=i/100;b=i/10%10;c=i%100%10;s=a*a*a+b*b*b+c*c*c;if(s==i){printf("%d\n",s);j++;}}if(j==0) printf("NONE");}

关于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

这个题有一点点难哦

#includeint main(){int i,j,n,sum,k;scanf("%d",&n);for(i=6;i<=n;i++) { for(j=1,sum=0;j<i;j++) if(i%j==0)sum=sum+j;//找出因子if(sum==i) {printf("%d its factors are ",i);for(k=1;k<i;k++) if(i%k==0)printf("%d ",k);//分别输出因子putchar('\n'); }}}

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

#includeint main(){int n,i;scanf("%d",&n);int a[n];a[0]=1;a[1]=1;for(i=0;i<n;i++){a[i+2]=a[i]+a[i+1];//关键if(i<n-1)printf("%d ",a[i]);if(i==n-1)printf("%d",a[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)

计算大月小月

#includeint 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

#includeint 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);//注意输出时是一个数(五十三)而不是53return 0;}