A-B

本题要求你计算AB。不过麻烦的是,AB都是字符串 —— 即从字符串A中把字符串B所包含的字符全删掉,剩下的字符组成的就是字符串AB

输入格式:

输入在2行中先后给出字符串AB。两字符串的长度都不超过104,并且保证每个字符串都是由可见的ASCII码和空白字符组成,最后以换行符结束。

输出格式:

在一行中打印出AB的结果字符串。

输入样例:

1
2
I love GPLT!  It's a fun game!
aeiou

输出样例:

1
I lv GPLT!  It's  fn gm!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <string.h>
int main(void){
int k=1;
char a [10000];
char b [10000];
gets(a);
gets(b);
for (int i=0;i<strlen(a);i++){
for (int z=0;z<strlen(b);z++){
if(a[i]==b[z]){
k=0;
continue;
}
}
if (k){
printf("%c",a[i]);
}
k=1;
}
}
// 这个代码让我最想不到的是直接输出字母,本来我想的是用另外一个数组来盛放字符串,但是这样子就会运行超时,按照上面的方法,用k做标识符一直循环,很方便

说反话-加强版

给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。

输入格式:

测试输入包含一个测试用例,在一行内给出总长度不超过500 000的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用若干个空格分开。

输出格式:

每个测试用例的输出占一行,输出倒序后的句子,并且保证单词间只有1个空格。

输入样例:

1
Hello World   Here I Come

输出样例:

1
Come I Here World Hello
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>
#include <string.h>
int main(void){
char s1[500001];
char s2[500001];
gets(s1);
int length=strlen(s1);
while(s1[length]==' '){
length--; // 先去除末尾多余的空格,这个操作也很重要,保证一开始录入的就是单词
}
int j=0,k,flag=1; //flag是表明是否是第一个单词
for(int i=length-1;i>=0;i--){
if(s1[i]!=' '){ //给s2中转载一个单词
s2[j]=s1[i];
j++;
}else if(s1[i]==' '&&s1[i+1]!=' '){
if(flag==1){ // 这是第一个单词的输出,单词前不需要加空格
for(k=j-1;k>=0;k--){
printf("%c",s2[k]);
}
flag++;
}else{
printf(" "); //这是后续单词的输出,单词前加空格
for(k=j-1;k>=0;k--){
printf("%c",s2[k]);
}
}
j=0; // 每次的单词输出完后,就会从s2[0]重新开始,一个单词一个单词的输出
}
}
if(s1[0]!=' '&&flag!=1){ // 防止只有一个单词的情况
printf(" ");
for(k=j-1;k>=0;k--){
printf("%c",s1[k]);
}
}
return 0;
}
//整个代码的逻辑其实非常简单,主要是s2这个数组用来承载每个单词非常巧妙,还有一些临界的处理,比如末尾空格处理和第一个单词的处理

顺时针矩阵

读入20内正整数正整数n,输出顺时针分布的矩阵。矩阵内容为1,2,。。。到n*n。

输入格式:

每个实例包含一个20内正整数。

输出格式:

顺时针分布的矩阵,每个数据占4位。

输入样例:

1
>7

输出样例:

1
2
3
4
5
6
7
19  20  21  22  23  24   1
18 37 38 39 40 25 2
17 36 47 48 41 26 3
16 35 46 49 42 27 4
15 34 45 44 43 28 5
14 33 32 31 30 29 6
13 12 11 10 9 8 7
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
#include <stdio.h>  

int main() {
int n;
scanf("%d", &n);
int matrix[20][20] = {0};

int num = 1;
int top = 0, bottom = n - 1, left = 0, right = n - 1;

while (num <= n * n) {

for (int i = top; i <= bottom; i++) {
matrix[i][right] = num++;
}
right--;

for (int i = right; i >= left; i--) {
matrix[bottom][i] = num++;
}
bottom--;

for (int i = bottom; i >= top; i--) {
matrix[i][left] = num++;
}
left++;

for (int i = left; i <= right; i++) {
matrix[top][i] = num++;
}
top++;
}

// 输出矩阵
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("%4d", matrix[i][j]);
}
printf("\n");
}

return 0;
}
// 1.这道题设了top,bottom,left,right来设定某个阶段的边界值,一开始我是用i,j来设定,但是发现循环中的i,j的变化不好控制,后来我企图用长度来控制也失败了,最后GPT告诉我用一个点一个变量的来限定二维数组的边界,巧妙
// 2.注意每个循环的条件,两边都是闭合的,恰好可以符合,一开始我一直想着左闭右开,但是失败了

杨辉三角

本题要求按照规定格式打印前N行杨辉三角。

输入格式:

输入在一行中给出N(1≤N≤10)。

输出格式:

以正三角形的格式输出前N行杨辉三角。每个数字占固定4位。

输入样例:

1
6

输出样例:

1
2
3
4
5
6
     1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
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
#include <stdio.h>  

int main() {
int n;
scanf("%d", &n);
int triangle[10][10] = {0};

// 构建杨辉三角
for (int i = 0; i < n; i++) {
triangle[i][0] = 1; //这两边的一先放置
triangle[i][i] = 1;
for (int j = 1; j < i; j++) {
triangle[i][j] = triangle[i - 1][j - 1] + triangle[i - 1][j];
}
}

// 输出杨辉三角
for (int i = 0; i < n; i++) {
// 输出每行前面的空格
for (int k = 0; k < n - i - 1; k++) {
printf(" ");
}
for (int j = 0; j <= i; j++) {
printf("%4d", triangle[i][j]);
}
printf("\n");
}

return 0;
} //本题就是先把杨辉三角放入二维数组中,构建的时候不要去想具体三角形的模样,只要知道对应数字规律就行,第n行有n+1个数

上面代码构造出来的二维数组是这样的

1

1 1

1 2 1

1 3 3 1.


求整数序列中出现次数最多的数

本题要求统计一个整型序列中出现次数最多的整数及其出现次数。

输入格式:

输入在一行中给出序列中整数个数N(0<N≤1000),以及N个整数。数字间以空格分隔。

输出格式:

在一行中输出出现次数最多的整数及其出现次数,数字间以空格分隔。题目保证这样的数字是唯一的。

输入样例:

1
>10 3 2 -1 5 3 4 3 0 3 2

输出样例:

1
>3 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
#include <stdio.h>

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

int arr [n];
for (int i=0;i<n;i++){
scanf("%d",&arr[i]);
}
int count=1;
int index =0;
for(int i=0;i<n;i++){
int count1= 1;
for(int j=i+1;j<n;j++){
if(arr[i]==arr[j]){
count1++;
}
}
if(count1>count){
index=i;
count=count1;
}
}
printf("%d %d\n",arr[index],count);
return 0;
}
//这道题很有趣,主要用了两种思路,一种是数列的序号代替数列实际的值,其次是用了简化版冒泡排序的思路来算出他的最大值(所以套了两层循环)--本身题目不难。

出生年

以上是新浪微博中一奇葩贴:“我出生于1988年,直到25岁才遇到4个数字都不相同的年份。”也就是说,直到2013年才达到“4个数字都不相同”的要求。本题请你根据要求,自动填充“我出生于y年,直到x岁才遇到n个数字都不相同的年份”这句话。

输入格式:

输入在一行中给出出生年份y和目标年份中不同数字的个数n,其中y在[1, 3000]之间,n可以是2、或3、或4。注意不足4位的年份要在前面补零,例如公元1年被认为是0001年,有2个不同的数字0和1。

输出格式:

根据输入,输出x和能达到要求的年份。数字间以1个空格分隔,行首尾不得有多余空格。年份要按4位输出。注意:所谓“n个数字都不相同”是指不同的数字正好是n个。如“2013”被视为满足“4位数字都不同”的条件,但不被视为满足2位或3位数字不同的条件。

输入样例1:

1
1988 4

输出样例1:

1
25 2013

输入样例2:

1
1 2

输出样例2:

1
0 0001
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
#include <stdio.h>  

int main(void){
int year;
scanf("%d", &year);
int n;
scanf("%d", &n);
int count = 0;
int m = year;
while (1) {
count = 0; // 重置 count
int arr[10] = {0};
int x = year;
arr[x % 10]++;
x = x / 10;
arr[x % 10]++;
x = x / 10;
arr[x % 10]++;
arr[x / 10]++;
for (int i = 0; i < 10; i++) {
if (arr[i] != 0) {
count++;
}
}
if (count == n) {
break;
}
year++;
}
printf("%d %04d", year - m, year);
return 0;
}
// 重点就是可以用数组的 index 来表示具体的数值,从而用对应的值表示次数

质数

本题要求计算并输出不超过n的最大的k个素数以及它们的和。

输入格式:

输入在一行中给出n(10≤n≤10000)和k(1≤k≤10)的值。

输出格式:

在一行中按下列格式输出:

1
素数1+素数2+…+素数k=总和值

其中素数按递减顺序输出。若n以内不够k个素数,则按实际个数输出。

输入样例1:

1
1000 10

输出样例1:

1
997+991+983+977+971+967+953+947+941+937=9664

输入样例2:

1
12 6

输出样例2:

1
11+7+5+3+2=28
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
#include<stdio.h>

int main(void){
int Maxnum;
int n;
scanf("%d %d",&Maxnum,&n);
int sum=0;
int count=0;
for(int i=Maxnum;i>=2;i--){
int flag =1;
for(int j=2;j*j<=i;j++){
if(i%j==0){
flag=0;
break;
}
}
if(flag){
sum+=i;
if(!count){
printf("%d",i);
}else{
printf("+%d",i);
}
count++;
}
if(count==n) break;
}
printf("=%d\n",sum);
return 0;
}
//质数的常规写法,没啥好说的,就留念一下

找出不是两个数组共有的元素

给定两个整型数组,本题要求找出不是两者共有的元素。

输入格式:

输入分别在两行中给出两个整型数组,每行先给出正整数N(≤20),随后是N个整数,其间以空格分隔。

输出格式:

在一行中按照数字给出的顺序输出不是两数组共有的元素,数字间以空格分隔,但行末不得有多余的空格。题目保证至少存在一个这样的数字。同一数字不重复输出。

输入样例:

1
2
10 3 -5 2 8 0 3 5 -15 9 100
11 6 4 8 2 6 -5 9 0 100 8 1

输出样例:

1
3 5 -15 6 4 1
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
#include <stdio.h>
int main(void){
int a1[20]= {0};
int a2[20]={0};
int a3[40]={0};
int n, m;
// 输入数据
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a1[i]);
scanf("%d",&m);
for(int i=0;i<m;i++)
scanf("%d",&a2[i]);

// 因为两个数组长度有差异,所以这里通过正反两次的遍历来消除长度差异
int k =0; // k 是a3的索引
for(int i=0;i<n;i++){
int flag =1;
for(int j=0;j<m;j++){
if(a1[i]==a2[j])
flag=0;
}
if(flag)
a3[k++]=a1[i];
}
for(int i=0;i<m;i++){
int flag=1;
for(int j=0;j<n;j++){
if(a2[i]==a1[j])
flag=0;
}
if(flag)
a3[k++]=a2[i];
}
//因为上面的方法,a3是会含有重复的元素的,所以只需要输出其中一个
for(int i=0;i<k;i++){
int flag=1;
for(int j=0;j<i;j++) //这边J<i可以遍历更少次数完成任务,其实写j<k差不多
if(a3[i]==a3[j])
flag=0;
if(flag){
if(!i)
printf("%d",a3[i]);
else
printf(" %d",a3[i]);
}
}
return 0;
}

敲笨钟

微博上有个自称“大笨钟V”的家伙,每天敲钟催促码农们爱惜身体早点睡觉。为了增加敲钟的趣味性,还会糟改几句古诗词。其糟改的方法为:去网上搜寻压“ong”韵的古诗词,把句尾的三个字换成“敲笨钟”。例如唐代诗人李贺有名句曰:“寻章摘句老雕虫,晓月当帘挂玉弓”,其中“虫”(chong)和“弓”(gong)都压了“ong”韵。于是这句诗就被糟改为“寻章摘句老雕虫,晓月当帘敲笨钟”。

现在给你一大堆古诗词句,要求你写个程序自动将压“ong”韵的句子糟改成“敲笨钟”。

输入格式:

输入首先在第一行给出一个不超过 20 的正整数 N。随后 N 行,每行用汉语拼音给出一句古诗词,分上下两半句,用逗号 , 分隔,句号 . 结尾。相邻两字的拼音之间用一个空格分隔。题目保证每个字的拼音不超过 6 个字符,每行字符的总长度不超过 100,并且下半句诗至少有 3 个字。

输出格式:

对每一行诗句,判断其是否压“ong”韵。即上下两句末尾的字都是“ong”结尾。如果是压此韵的,就按题面方法糟改之后输出,输出格式同输入;否则输出 Skipped,即跳过此句。

输入样例:

1
2
3
4
5
6
5
xun zhang zhai ju lao diao chong, xiao yue dang lian gua yu gong.
tian sheng wo cai bi you yong, qian jin san jin huan fu lai.
xue zhui rou zhi leng wei rong, an xiao chen jing shu wei long.
zuo ye xing chen zuo ye feng, hua lou xi pan gui tang dong.
ren xian gui hua luo, ye jing chun shan kong.

输出样例:

1
2
3
4
5
xun zhang zhai ju lao diao chong, xiao yue dang lian qiao ben zhong.
Skipped
xue zhui rou zhi leng wei rong, an xiao chen jing qiao ben zhong.
Skipped
Skipped
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
51
52
#include <stdio.h>
#include <string.h>
void Judge (char * left, char * right){
char * start =left;
// 这个处理很巧妙,可以先让逗号变成'\0',变成一个字符串。
while(*left!=','){
left++;
}
*left='\0';
int flag1 =0;
if(strcmp(left-3,"ong")==0){
flag1=1;
}
*left =',';
// 寻找第二句诗是否押韵
*right='\0';
int flag2=0;
if(strcmp(right-3,"ong")==0){
flag2=1;
}
// 找到需要修改成lao beng zhong 的地方
int count=0;
while(right--){
if(*right== ' ')
count++
if (count==3)
break;
}
*right='\0';
// 需要两句诗都是Ong结尾才行
if(flag ==1 && flag2==1){
printf("%s",start);
printf(" qiao ben zhong.\n");
}else{
printf("Skipped\n")
}

}
int main (void){
int n=0;
scanf("%d",&n);
getchar();
char arr[101]={0};
int i=0;
for(i=0;i<n;i++){
gets(arr);
int len =strlen(arr);
Judge(arr,arr+len-1);
}
}
// 这个代码用指针解决更加的方便
// 还有指针配合strcmp的使用,很舒服,这是之前没想到的

大数求和

大林最近看了一些大数计算的资料,觉得颇有心得,于是他在课堂上出了一道简单的大数加法给学生做练习,当然两个加数都是超过int和long所能表示的数的范围。这让他的学生们不禁陷入了沉思,怎么办呢?做不出来的话期末成绩可能要59分了。在这危急时刻,有个聪明的阿飞同学挺身而出,通过仔细观察,他发现两个高位数的正整数相加,可以把这两个正整数分别拆成两个低位数的正整数之间的加法和进位运算。经过不懈努力,他成功地解决了这道题,获得了大林的表扬。请大家向阿飞同学学习,也编写类似程序来解决这个问题。

输入格式:

两个30位正整数。

输出格式:

输入样例:

1
2
111123456789101112131715161718
222345678910111213141516171819

输出样例:

1
333469135699212325273231333537
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
#include <stdio.h>  

int main(void){
char a1[30]={'0'};
char a2[30]={'0'};
int a3[30]={0};

for(int i=0; i<30; i++){
scanf(" %c", &a1[i]);
}

for(int i=0; i<30; i++){
scanf(" %c", &a2[i]);
}

for(int i=0; i<30; i++){
a3[i] = a1[i]-'0' + a2[i]-'0';
}

for(int i =29; i>0; i--){
a3[i-1] += a3[i]/10;
a3[i] = a3[i]%10;
}

for(int i = 0; i<30; i++){
printf("%d", a3[i]);
}
printf("\n");
return 0;
}
// 大数求和就是把他放到一个数组里面,然后从后往前依次相加取模啥的
// sb题目一开始误导我说什么把数值拆开来,拆你个头,无语
// 最后我本来想要重新开一个a[0]来存放多出来的31位数,但是后来发现a[1]是两位数可以直接输出,不一定a[1]也是个位数,只要a[2:]是个位数就行了,我也是一坨

汉诺塔数列

汉诺塔是一个源于印度古老传说的益智玩具。据说大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘,大梵天命令僧侣把圆盘移到另一根柱子上,并且规定:在小圆盘上不能放大圆盘,每次只能移动一个圆盘。当所有圆盘都移到另一根柱子上时,世界就会毁灭。

1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, …

第 1 项为 1,表明移动 1 片圆盘的汉诺塔需 1 步;第 2 项为 3,表明移动 2 片圆盘的汉诺塔需 3 步;……,以此类推。请编写递归函数,求汉诺塔数列中任一项的值。

函数原型

1
double NumHanoi(int index);

说明:参数 index 为索引号(正整数),函数值为九连环数列第 index 项的值。

裁判程序

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

double NumHanoi(int index);

int main()
{
int n;
scanf("%d", &n);
printf("%.15g\n", NumHanoi(n));
return 0;
}

/* 你提交的代码将被嵌在这里 */

输入样例1

1
3

输出样例1

1
7

输入样例2

1
45

输出样例2

1
35184372088831

这道题的重点不是在考汉诺塔怎么写,而是考汉诺塔的次数

即用递归的方式实现pow(2,n)-1

1
2
3
4
5
6
7
8
double NumHanoi(int n){
if (n == 0) {
return 0;
} else {
return 2 * NumHanoi(n - 1) + 1;
}
}
// 递归还是好难
1
2
3
4
5
6
7
8
9
10
11
12
13
//下面是汉诺塔的实现方式
void moveDisk(char from, char to, int disk) {
printf("Move disk %d from rod %c to rod %c\n", disk, from, to);
}
void hanoi(int n, char source, char auxiliary, char destination) {
if (n == 1) {
moveDisk(source, destination, 1);
return;
}
hanoi(n - 1, source, destination, auxiliary); // 移动n-1个小盘子从左到中间
moveDisk(source, destination, n); //移动第N个盘子从左到右边
hanoi(n - 1, auxiliary, source, destination); //移动n-1个盘子从中间到右边
}

一帮一

7-5 一帮一

分数 13

作者 陈越

单位 浙江大学

“一帮一学习小组”是中小学中常见的学习组织方式,老师把学习成绩靠前的学生跟学习成绩靠后的学生排在一组。本题就请你编写程序帮助老师自动完成这个分配工作,即在得到全班学生的排名后,在当前尚未分组的学生中,将名次最靠前的学生与名次最靠后的异性学生分为一组。

输入格式:

输入第一行给出正偶数N(≤50),即全班学生的人数。此后N行,按照名次从高到低的顺序给出每个学生的性别(0代表女生,1代表男生)和姓名(不超过8个英文字母的非空字符串),其间以1个空格分隔。这里保证本班男女比例是1:1,并且没有并列名次。

输出格式:

每行输出一组两个学生的姓名,其间以1个空格分隔。名次高的学生在前,名次低的学生在后。小组的输出顺序按照前面学生的名次从高到低排列。

输入样例:

1
2
3
4
5
6
7
8
9
8
0 Amy
1 Tom
1 Bill
0 Cindy
0 Maya
1 John
1 Jack
0 Linda

输出样例:

1
2
3
4
Amy Jack
Tom Linda
Bill Maya
Cindy John

答案

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
#include <stdio.h>

struct Student{
int n;
char name[20];
};

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

struct Student stu[n];

for(int i=0;i<n;i++){
scanf("%d %s",&stu[i].n,stu[i].name);
}
int cnt =0;
int i=0;
while(cnt<n/2) {
if(stu[i].n==0){
for(int j=n-1;j>=0;j--){
if(stu[j].n==1){
printf("%s %s\n",stu[i].name,stu[j].name);
stu[j].n=3;
cnt++;
i++;
break;
}
}
}else if(stu[i].n==1){
if(stu[i].n==1){
for(int j=n-1;j>=0;j--){
if(stu[j].n==0){
printf("%s %s\n",stu[i].name,stu[j].name);
stu[j].n=3;
cnt++;
i++;
break;
}
}
}
}
}
return 0;
}

这是一道暑假的时候恶心得要死要活还做不出来的题目
现在能徒手把他做出来,还是有点开心的
这道题的难点就是最后的输出格式问题,因为不仅仅是男女问题,而且必须是成绩高的在前面
所以两个数组一男一女是不可实现的了
我的思路就是把用过了的人的性别标为3,这样子就不会出现重复用的情况,非常巧妙


统计单词数量(文件)

请编写函数,统计英文文章的单词数量。

函数原型

1
int CountWord(FILE *f);

说明:参数 f 为文件指针。函数值为该文件的单词数量。

裁判程序

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
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int CountWord(FILE *f);

int main()
{
FILE *f;
int n;
f = fopen("Story.txt", "r");
if (!f)
{
puts("文件无法打开!");
exit(1);
}

n = CountWord(f);

if (fclose(f))
{
puts("文件无法关闭!");
exit(1);
}

printf("单词数: %d\n", n);
return 0;
}

/* 你提交的代码将被嵌在这里 */

打开 Windows 记事本软件,复制下面的文章内容,保存文件并命名为“Story.txt”。

Story.txt

1
2
3
4
5
6
7
8
9
10
11
A Cure for a Headache

One day a man went into a chemist's shop and said, "Have you anything to cure a
headache?"
The chemist took a bottle from a shelf, held it under the gentleman's nose and
took out the cork. The smell was so strong that tears came into the man's eyes
and ran down his cheeks.
"What did you do that for?" he said angrily, as soon as he could get back his
breath.
"But that medicine has cured your headache, hasn't it?" said the chemist.
"You fool," said the man, "It's my wife that has the headache, not me!"

样例输入

1
(无)

输出样例

1
单词数: 108

注:一串连续的字母被定义为一个单词

答案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int CountWord (FILE * f){
int count =0;
char str;
int judge=0;
do{
str = fgetc(f);
if(isalpha(str)){
judge=1;
continue;
}
if(judge&&!isalpha(str)){
judge=0;
count++;
}
if(str==EOF) break;
}while(1);
return count;
}
//这道题受到某道题的影响,所以写了一下do while的形式
//个人感觉do while的形式会更加灵活,条件break更具有操作性
//这道题的思路就是 用一个judge表示前一个读取的是字母,而现在的str是非字母,因此count++;
//这边用isalphaa来判定是否为字母,当然(str==EOF)的位置要放好,不然的话会造成最后一个字母没有读取的情况,非常真实

文件读写操作

编写函数,从给定的输入文本文件中按行读入,并按行写入给定的输出文件中。要求:1)去除每行的前导空格或制表符。2)每行前加行号。

函数接口定义:

1
void fileRW(FILE *fin,FILE *fout);

其中finfout 都是用户传入的参数,分别是读入文件和输出文件的指针(已按要求打开)。

裁判测试程序样例:

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
void fileRW(FILE *fin,FILE *fout);
int main(){
char fname[20];gets(fname);
FILE *fpr=fopen(fname,"r");
FILE *fpw=fopen("file2.txt","w");
fileRW(fpr,fpw);
fclose(fpr);fclose(fpw);
return 0;
}
/* 请在这里填写答案 */

输入样例:

输入文件名:file1.cpp,其中内容为:

1
2
3
4
5
6
7
void fileW(){
FILE *fp1=fopen("myfile.data","w");
int i=123;float x=3.14159;
fprintf(fp1,"%d,%5d,%5.3f\n",i,-i,x);
fprintf(stdout,"%d,%5d,%5.3f\n",i,-i,x);
fclose(fp1);
}

输出样例:

文件:file2.txt,其中内容为:

1
2
3
4
5
6
7
1:void fileW(){
2:FILE *fp1=fopen("myfile.data","w");
3:int i=123;float x=3.14159;
4:fprintf(fp1,"%d,%5d,%5.3f\n",i,-i,x);
5:fprintf(stdout,"%d,%5d,%5.3f\n",i,-i,x);
6:fclose(fp1);
7:}

答案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void fileRW(FILE *fin,FILE *fout)
{
char str;
int i=1,j=1;
do // j表示单词的数量,i表示换行符的数量
// 其实会发现 i==j 的时候就是新起一行的时候,非常关键
{
str=fgetc(fin);
if(i==j&&str!=EOF)
{
fprintf(fout,"%d:",j++);
while(str==' '||str=='\t')
str=fgetc(fin);
}
if(str=='\n')
i++;
if(str==EOF)
break;
fputc(str,fout); //记得要最后输出,在EOF后面
}
while(1);
}

这道题最狗屎的地方就是空格的缩进

之所以选择do while的方式,是因为这个语句更加灵活

可以在多个限制条件中随机选择条件break;