题目
主管期望你来实现英文输入法单词联想功能,需求如下:
- 依据用户输入的单词前缀,从已输入的英文语句中联想出用户想输入的单词。
- 按字典序输出联想到的单词序列,如果联想不到,请输出用户输入的单词前缀。
注意
- 英文单词联想时区分大小写
- 缩略形式如"don’t" 判定为两个单词 "don"和 “t”
- 输出的单词序列不能有重复单词,且只能是英文单词,不能有标点符号
输入
输入两行
首行输入一段由英文单词word
和标点
构成的语句str
接下来一行为一个英文单词前缀pre
0 < word.length() <= 20
0 < str.length() <= 10000
0 < pre.length() <= 20
输出
输出符合要求的单词序列或单词前缀
存在多个时,单词之间以单个空格分割
示例一
输入
I love you
He
输出
He
说明
用户已输入单词语句"I love you"
,
中提炼出"I"
,"love"
,"you"
三个单词
接下来用户输入"He"
,
从已经输入信息中无法联想到符合要求的单词
所以输出用户输入的单词前缀
示例一
输入
The furthest distance in the world,Is not between life and death,But when I stand in front or you,Yet you don't know that I love you.
f
输出
front furthest
代码
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 定义最大字符串长度常量
#define MAX_LEN 10001// 自定义比较函数,用于对字符串数组进行排序
int cmp(const void *a, const void *b) {return strcmp((const char *)a, (const char *)b);
}int main() {// 输入的英文语句char str[MAX_LEN];fgets(str, MAX_LEN, stdin);// 去除末尾换行符str[strcspn(str, "\n")] = '\0';// 用户输入的单词前缀char pre[21];scanf("%s", pre);// 将标点符号替换为空格以便处理单词for (int i = 0; str[i] != '\0'; i++) {if (!isalpha(str[i])) {str[i] = ' ';}}// 存储从输入语句中拆分出的所有单词char word[500][21];int count = 0;// 使用strtok函数分割字符串为单词char *token = strtok(str, " ");while (token != NULL) {strcpy(word[count++], token);token = strtok(NULL, " ");}// 存储与用户输入前缀匹配的单词char res[500][21];int res_count = 0;// 遍历所有单词,查找以pre为前缀的单词并存入res数组for (int i = 0; i < count; i++) {if (strncmp(word[i], pre, strlen(pre)) == 0) {strcpy(res[res_count++], word[i]);}}// 如果没有找到任何匹配的单词,则输出用户输入的单词前缀if (res_count == 0) {printf("%s\n", pre);return 0;}// 对匹配到的单词按字典序进行排序qsort(res, res_count, sizeof(res[0]), cmp);// 输出排序后的单词序列for (int i = 0; i < res_count; i++) {printf("%s ", res[i]);}// 输出最后一个单词后不带空格printf("\n");return 0;
}
注意
1、标点符号的去除
// 将标点符号替换为空格for (int i = 0; str[i] != '\0'; i++) {if (!isalpha(str[i])) {str[i] = ' ';}}
去除标点符号
2、cmp(const void *a, const void *b) {
// 自定义比较函数,用于对字符串数组进行排序
int cmp(const void *a, const void *b) {return strcmp((const char *)a, (const char *)b);
}
这段代码定义了一个名为 cmp
的函数,用于自定义排序规则。这个函数主要用于配合 C 语言标准库中的 qsort
函数对数组进行排序。
函数原型为:
int cmp(const void *a, const void *b);
参数说明:
const void *a
和const void *b
:这两个指针参数分别指向要比较的元素在数组中的地址,由于qsort
函数通用性很强,它可以处理任何类型的数据,所以这里使用了void*
类型,表示不指定具体类型。
在这个函数内部:
return strcmp((const char *)a, (const char *)b);
将两个 void*
类型的指针强制转换为 const char*
类型,这是因为我们的实际数据是字符串,需要调用 strcmp
函数来进行比较。strcmp
是 C 标准库提供的一个函数,用于比较两个字符串的大小(按字典顺序),返回值为:
- 如果
a
字符串小于b
字符串,则返回负数; - 如果
a
字符串等于b
字符串,则返回 0; - 如果
a
字符串大于b
字符串,则返回正数。
因此,cmp
函数实现了对传入的两个字符串按照字典序进行比较的功能,qsort
函数会根据这个比较结果来对包含字符串的数组进行升序排列。在本题中,我们使用 cmp
函数对找到的所有以给定前缀开头的单词数组进行排序。