c-moodle/homework/11994.c

106 lines
3.2 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 引入相关头文件
#include <stdio.h>
#include <string.h>
// 定义字符串和计数器等变量
#define MIN(i, j) (((i) < (j)) ? (i) : (j))
char ss[1005];
int x, dk;
// 定义结构体,用来存放每一个单词的信息
struct word {
char s[1005];
int k;
} wd[1005];
// 交换两个结构体
void swap(struct word* a, struct word* b) {
struct word c;
c = *a;
*a = *b;
*b = c;
}
// 用来比较两个字符串的大小,比较时先按照字典序排序,再比较字符串长度
int cmp(char s1[], char s2[]) {
int l1 = strlen(s1), l2 = strlen(s2);
for (int i = 0; i < MIN(l1, l2); i++) {
if (s1[i] > s2[i])
return 1;
else if (s1[i] < s2[i])
return -1;
}
if (l1 == l2)
return 0;
else if (l1 > l2)
return 1;
else
return -1;
}
// 用来查找某个单词在结构体数组中的位置,找到则返回该单词所在的下标,不存在则返回-1
int xz(char s1[]) {
for (int i = 0; i < dk; i++) {
if (cmp(wd[i].s, s1) == 0)
return i;
}
return -1;
}
// 冒泡排序,根据单词出现次数和字典序排序,使得前十个单词分别为出现次数最多的十个单词
void sort() {
for (int i = 0; i < dk; i++) {
for (int j = 0; j < dk - i - 1; j++) {
// 如果j位置的单词出现的次数小于j+1位置的单词出现的次数
// 或者j和j+1位置的单词出现的次数相同但是j位置的单词字典序大于j+1位置的单词字典序
// 则交换两个单词在结构体数组中的位置
if (wd[j].k < wd[j + 1].k || (wd[j].k == wd[j + 1].k && cmp(wd[j].s, wd[j + 1].s) == 1)) {
swap(&wd[j], &wd[j + 1]);
}
}
}
}
// main函数
int main() {
// 读入字符串
gets(ss);
for (int i = 0; i <= strlen(ss); i++) {
// 统计空格数量,用来确定单词的位置
if (ss[i] == ' ' && ss[i - 1] == ' ') {
x++;
}
// 如果已经到了字符串结尾,或者当前字符是空格但前一个字符不是空格,
// 则说明当前位置是一个单词的结尾
if (i == strlen(ss) || (ss[i] == ' ' && ss[i - 1] != ' ')) {
char ls[1005] = "";
int flag = 1;
// 将单词转换为小写,并将该单词存储到结构体数组中
for (int k = x; k < i; k++) {
if (ss[k] >= 'A' && ss[k] <= 'Z') {
ss[k] += 32;
}
ls[k - x] = ss[k];
}
// 更新空格数量
x = i + 1;
// 如果结构体数组中已存在该单词则将该单词的次数加1否则添加一个新单词到结构体数组中
if (xz(ls) != -1) {
wd[xz(ls)].k++;
} else {
for (int j = 0; j < strlen(ls); j++)
wd[dk].s[j] = ls[j];
wd[dk].k = 1;
dk++;
}
}
}
// 对结构体数组进行排序
sort();
// 输出前十个单词和出现次数
for (int i = 0; i < MIN(dk, 10); i++) {
printf("%s:%d\n", wd[i].s, wd[i].k);
}
return 0;
}