头歌C语言实验 练习10:数组与字符串

第1关:成绩排序

问题描述
在一个班上最多有50名学生。
期末考试结束后,班主任张老师需要对班上学生的成绩按照从高到低的顺序排序,以便可以查看班上考得最好的前几名同学的成绩。
聪明的你,能利用所学的知识,编写一段程序,帮助辛苦的张老师完成这个任务吗?

输入
输入包括两行:
输入的第一行包括若干个浮点数的百分制成绩,最后以一个负数作为结束标记。
输入的第二行只有一个整数n,表示张老师需要查看成绩最高的前n个成绩。

提示:输入数据的第一行最多可能有51个浮点数。

输出
按照从高到低的顺序输出成绩最高的前m个成绩,每个成绩保留1位小数,并且单独占一行输出。

提示:输入的n可能大于实际成绩个数,此时应该按照实际成绩个数输出。

输入示例
93.65 87.46 56.3 97.37 93.5 89.6 78.3 89.63 95 48.42 96.54 -4
5

输出示例
97.4
96.5
95.0
93.7
93.5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <stdio.h>
void sort(double score[], int n);
int main() {
int n, i = 0, num = 0;
double score[51];
double t;
while (1) {
scanf("%lf", &t);
if (t >= 0) {
score[i] = t;
i++;
num++;
} else {
break;
}
}
scanf("%d", &n);
sort(score, num);
if (n > num) {
n = num;
}
for (i = 0; i < n; i++) {
printf("%.1lf\n", score[i]);
}
return 0;
}
// 冒泡排序
void sort(double score[], int n) {
int i,j;
double t;
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(score[j]<score[j+1]){
t=score[j];
score[j]=score[j+1];
score[j+1]=t;
}
}
}
}

第2关:计算字符串长度

问题描述
字符串长度是指字符串中实际包含的字符个数。在C语言中,按照C语言中字符串的规范,字符串的长度可以定义为:“<font color=green>字符数组中第一个‘\0’字符之前的字符的个数 </font>”。
请编写一个自定义函数,不调用系统库函数strlen(),计算字符串的长度。自定义函数可以声明为:
int getStrLen(char str[]);
主函数中由用户输入一个长度不超过100的字符串(可能包含空格),调用自定义函数得到字符串长度后输出。

输入
一行字符串,使用gets(str)方法读取此行字符串。

输出
一个非负整数,表示字符串的长度。

输入示例
I am a dreamer on air.

输出示例
22

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>

/* 函数声明 */
int getStrLen(char str[]);

int main() {
/* 在这里补充代码完成整个程序的功能 */
char str[101];
int len;
gets(str);
len=getStrLen(str);
printf("%d",len);
return 0;
}
/* 函数实现 */
int getStrLen(char str[]) {
/* 请在下面补充你的代码实现函数功能 */
int i;
for(i=0;str[i]!='\0';i++);
return i;
}

第3关:字符替换

问题描述
把一个字符串中特定的字符用给定的字符替换,得到一个新的字符串。

输入
输入数据有多行,第一行是要处理的字符串的数目n。
其余各行中每行内容由一个空格分开的三个部分组成:
第一个部分是一个字符串,即需要替换字符的字符串,字符串中没有空格并且长度小于等于30个字符;
第二个部分是一个字符,即原字符串中需要被替换的字符;
第三个部分是一个字符,即用于替换的新字符。

输出
有多行,每行输出对应的替换后的字符串。

输入示例
1
hello-how-are-you o O

输出示例
hellO-hOw-are-yOu

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<stdio.h>
void replace(char str[],char a,char b){
int i;
for(i=0;str[i]!='\0';i++){
if(str[i]==a){
str[i]=b;
}
}
}
int main(){
int n,i,j;
char str[31];
char a,b;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%s %c %c",&str,&a,&b);
replace(str,a,b);
for(j=0;str[j]!='\0';j++){
printf("%c",str[j]);
}
printf("\n");
}
return 0;
}

第4关:统计字符数

问题描述
判断一个由a~z这26个小写字母组成的字符串中哪个字母出现的次数最多。

输入
第一行是测试数据的组数n,接下来的每组测试数据单独占1行,是一个由a~z这26个小写字母组成的字符串,每行数据不超过1000个字符且非空。
提示:每个字符串中不会包含空格。

输出
n行,每行输出对应一个输入,包括出现次数最多的字符和该字符出现的次数,中间是一个空格。如果有多个字符出现的次数相同且最多,那么输出ASCII码最小的那一个字符。

输入示例
2
abbccc
adfadffasdf

输出示例
c 3
f 4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include<stdio.h>
void Count(char str[],int count[]){
int i;
for(i=0;str[i]!='\0';i++){
count[str[i]-'a']++;
}
}
int Findmax(int count[]){
int max=0;
int i;
int maxalpha=0;
for(i=0;i<26;i++){
if(count[i]>max){
max=count[i];
maxalpha=i;
}
}
return maxalpha;
}
void ArrtoZero(int arr[],int n){
int i;
for(i=0;i<n;i++){
arr[i]=0;
}
}
int main(){
int i,n,max;
int count[26]={0};
char str[1001];
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%s",&str);
Count(str,count);
max=Findmax(count);
printf("%c %d\n",'a'+max,count[max]);
ArrtoZero(count,26);
}
return 0;
}

第5关:浮点数格式

问题描述
输入n(0<n≤50)个浮点数,要求把这n个浮点数重新排列(并非排序,而是对齐)后再输出。每个浮点数中都有小数点且总长度不超过50位。

输入
第1行是一个正整数n(n≤50),后面n行每行一个浮点数,每个浮点数中都保证小数点会出现。浮点数的长度不超过50位,注意这里的浮点数会超过系统标准浮点数的表示范围。

输出
n行,每行对应一个输入。要求每个浮点数的小数点在同一列上,同时要求首列上不会全部是空格。

输入示例
2
-0.34345
4545.232

输出示例
-0.34345
4545.232

提示
输入的浮点数位数很长,远远超过了float甚至double类型所能表示的范围。并且这些浮点数不需要参与算数运算,因此可以把它们考虑为字符串进行处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void FindPoint(char str[][51], int *point, int *beforepoint, int n){
int i, j;
for (i = 0; i < n; i++){
for (j = 0; str[i][j] != '\0'; j++){
if (str[i][j] == '.'){
point[i] = j;
break;
}
else{
beforepoint[i]++;
}
}
}
}
int Findmax(int *point, int n){
int max = point[0];
int i;
for (i = 1; i < n; i++){
if (point[i] > max)
max = point[i];
}
return max;
}
void Printstr(char str[][51], int *beforepoint, int n, int max){
int i, j;
for (i = 0; i < n; i++){
for (j = 0; j < max - beforepoint[i]; j++){
printf(" ");
}
puts(str[i]);
}
}
int main(){
int n, i, max;
int *point;
int beforepoint[50]={0};
char str[50][51];
scanf("%d", &n);
point=(int*)malloc(sizeof(int)*n);
for (i = 0; i < n; i++){
scanf("%50s", str[i]);
}
FindPoint(str, point, beforepoint, n);
max = Findmax(point, n);
Printstr(str, beforepoint, n, max);
return 0;
}