单词匹配
已知一个包含若干英文单词的词典(1≤n≤100),对任意输入的某一个单词 word(字典中的单词和给定单词 word 的长度均不超过 255),进行如下查询操作:
⑴ word 在词典中的位置。
⑵ 词典中仅有一个字符与 word 不匹配的单词位置。
⑶ 词典中比 word 多(或少)一个字符(除此字符外其余字符均匹配)的单词位置。
⑷ 上述查找时,如有多个单词符合条件,仅输出其第一个单词的位置。
【功能要求】
⑴ 词典以文本文件格式存放,每行一个单词。
⑵ 查找完成后,输出找到的单词在词典中的位置以及该单词,如未找到指定单词,应给出提示信息。
//单词匹配
//已知一个包含若干英文单词的词典(1≤n≤100),对任意输入的某一个单词 word(字典中的单词和给定单词 word 的长度均不超过 255),进行如下查询操作:
//⑴ word 在词典中的位置。
//⑵ 词典中仅有一个字符与 word 不匹配的单词位置。
//⑶ 词典中比 word 多(或少)一个字符(除此字符外其余字符均匹配)的单词位置。
//⑷ 上述查找时,如有多个单词符合条件,仅输出其第一个单词的位置。
//【功能要求】
//⑴ 词典以文本文件格式存放,每行一个单词。
//⑵ 查找完成后,输出找到的单词在词典中的位置以及该单词,如未找到指定单词,应给出提示信息。
#include <stdio.h>
#include <string.h>
int strdiff(char *a,char *b) {
int la,lb,diff,i;
la=strlen(a);
lb=strlen(b);
if (la<1 || lb<1 || la!=lb) return -1;
diff=0;
for (i=0;i<la;i++) if (a[i]!=b[i]) diff++;
return diff;
}
int strnear(char *a,char *b) {
int la,lb,near,i,j,k;
la=strlen(a);
lb=strlen(b);
if (la<1 || lb<1 || !(la==lb+1 || la+1==lb)) return -1;
near=0;
if (la==lb+1) {
for (i=0;i<la;i++) {
k=0;
for (j=0;j<lb;j++) {
if (k==i) {k++;j--;}
else {
if (a[k]!=b[j]) break;
k++;
}
}
if (j>=lb) return 1;
}
}
if (la+1==lb) {
for (i=0;i<lb;i++) {
k=0;
for (j=0;j<la;j++) {
if (k==i) {k++;j--;}
else {
if (b[k]!=a[j]) break;
k++;
}
}
if (j>=la) return 1;
}
}
return 0;
}
int main() {
FILE *f;
int i,n;
char ln[255+2];
char d[100][255+1];
f=fopen("dict.txt","r");
if (NULL==f) {
printf("Can not open dict.txt!\n");
return 1;
}
i=0;
while (1) {
if (NULL==fgets(ln,255+2,f)) break;
if ('\n'==ln[strlen(ln)-1]) ln[strlen(ln)-1]=0;
strcpy(d[i],ln);
i++;
if (i>=100) break;
}
n=i;
fclose(f);
printf("dictionary:\n");
for (i=0;i<n;i++) printf("%d %s\n",i+1,d[i]);
printf("input a word:");
fflush(stdout);
fgets(ln,255+2,stdin);
if ('\n'==ln[strlen(ln)-1]) ln[strlen(ln)-1]=0;
//⑴ word 在词典中的位置。
printf("find '%s' ...\n",ln);
for (i=0;i<n;i++) if (0==strcmp(ln,d[i])) break;
if (i<n) printf("%d %s\n",i+1,ln); else printf("Can not find '%s'!\n",ln);
//⑵ 词典中仅有一个字符与 word 不匹配的单词位置。
printf("find word only 1 char different from '%s' ...\n",ln);
for (i=0;i<n;i++) if (1==strdiff(ln,d[i])) break;
if (i<n) printf("%d %s\n",i+1,d[i]); else printf("Can not find word only 1 char different from '%s'!\n",ln);
//⑶ 词典中比 word 多(或少)一个字符(除此字符外其余字符均匹配)的单词位置。
printf("find word only 1 char more/less than '%s' ...\n",ln);
for (i=0;i<n;i++) if (1==strnear(ln,d[i])) break;
if (i<n) printf("%d %s\n",i+1,d[i]); else printf("Can not find word only 1 char more/less than '%s'!\n",ln);
return 0;
}
//d:\test>test.exe
//dictionary:
//1 a
//2 bb
//3 ccc
//4 dddd
//input a word:a
//find 'a' ...
//1 a
//find word only 1 char different from 'a' ...
//Can not find word only 1 char different from 'a'!
//find word only 1 char more/less than 'a' ...
//Can not find word only 1 char more/less than 'a'!
//
//d:\test>test.exe
//dictionary:
//1 a
//2 bb
//3 ccc
//4 dddd
//input a word:ab
//find 'ab' ...
//Can not find 'ab'!
//find word only 1 char different from 'ab' ...
//2 bb
//find word only 1 char more/less than 'ab' ...
//1 a
//
//d:\test>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_WORD_LEN 256
// 字典树节点
typedef struct TrieNode
{
// 当前节点的字符
char c;
// 是否是单词的结尾
int is_end;
// 子节点
struct TrieNode *children[26];
} TrieNode;
// 创建一个新的字典树节点
TrieNode *create_trie_node(char c)
{
TrieNode *node = (TrieNode *)malloc(sizeof(TrieNode));
node->c = c;
node->is_end = 0;
memset(node->children, 0, sizeof(node->children));
return node;
}
// 在字典树中插入一个单词
void insert_word(TrieNode *root, const char *word)
{
TrieNode *node = root;
for (int i = 0; word[i] != '\0'; i++)
{
int index = word[i] - 'a';
if (node->children[index] == NULL)
{
node->children[index] = create_trie_node(word[i]);
}
node = node->children[index];
}
node->is_end = 1;
}
// 在字典树中查找单词
int find_word(TrieNode *root, const char *word)
{
TrieNode *node = root;
for (int i = 0; word[i] != '\0'; i++)
{
int index = word[i] - 'a';
if (node->children[index] == NULL)
{
return -1;
}
node = node->children[index];
}
return node->is_end ? 1 : 0;
}
// 在字典树中查找仅有一个字符不匹配的单词
int find_word_with_one_mismatch(TrieNode *root, const char *word)
{
TrieNode *node = root;
int mismatches = 0;
for (int i = 0; word[i] != '\0'; i++)
{
int index = word[i] - 'a';
if (node->children[index] == NULL)
{
mismatches++;
if (mismatches > 1)
{
return -1;
}
for (int j = 0; j < 26; j++)
{
if (j == index)
{
continue;
}
if (node->children[j] != NULL)
{
node = node->children[j];
break;
}
}
}
else
{
node = node->children[index];
}
}
return mismatches == 1 && node->is_end ? 1 : 0;
}
// 在字典树中查找比指定单词多或少一个字符的单词
int find_word_with_one_extra_char(TrieNode *root, const char *word, int extra)
{
TrieNode *node = root;
for (int i = 0; word[i] != '\0'; i++)
{
int index = word[i] - 'a';
if (node->children[index] == NULL)
{
return -1;
}
node = node->children[index];
}
if (extra == 1)
{
// 查找多一个字符的单词
for (int i = 0; i < 26; i++)
{
if (node->children[i] != NULL && node->children[i]->is_end)
{
return 1;
}
}
}
else
{
// 查找少一个字符的单词
if (node->is_end)
{
return 1;
}
}
return 0;
}
int main()
{
// 创建字典树
TrieNode *root = create_trie_node('\0');
insert_word(root, "hello");
insert_word(root, "world");
insert_word(root, "wonderful");
insert_word(root, "word");
// 查找单词在词典中的位置
int result = find_word(root, "word");
if (result == 1)
{
printf("Found word in dictionary\n");
}
else
{
printf("Word not found in dictionary\n");
}
// 查找词典中仅有一个字符与单词不匹配的单词位置
result = find_word_with_one_mismatch(root, "wrd");
if (result == 1)
{
printf("Found word in dictionary with one character mismatch\n");
}
else
{
printf("Word not found in dictionary with one character mismatch\n");
}
// 查找词典中比单词多一个字符的单词位置
result = find_word_with_one_extra_char(root, "wonder", 1);
if (result == 1)
{
printf("Found word in dictionary with one extra character\n");
}
else
{
printf("Word not found in dictionary with one extra character\n");
}
// 查找词典中比单词少一个字符的单词位置
result = find_word_with_one_extra_char(root, "wonderfu", -1);
if (result == 1)
{
printf("Found word in dictionary with one missing character\n");
}
else
{
printf("Word not found in dictionary with one missing character\n");
}
return 0;
}
为了解决这个问题,我们可以使用一种数据结构叫做 Trie 树。
Trie 树(也称为字典树或前缀树)是一种树形结构,用于存储字典中的所有单词。它通过将每个单词按照字符顺序插入树中来构建字典。每个节点表示一个字符,并且每个节点都有若干子节点,表示与该字符相关的下一个字符。Trie 树的根节点表示空字符串,并且所有的单词都是从根节点开始的。
在 Trie 树中查找单词时,可以从根节点开始按照字符顺序依次匹配。如果找到了单词,则表示该单词在字典中。如果遇到了不匹配的字符,则表示字典中没有这个单词。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
// 定义 TrieNode 结构体。
struct TrieNode {
char c;
bool isWord;
struct TrieNode *children[26];
};
// 定义 Trie 结构体。
struct Trie {
struct TrieNode *root;
};
// 向 Trie 树中插入单词。
void insert(struct TrieNode *node, const char *word) {
if (*word == '\0') {
// 如果遇到了字符串的结尾,则将当前节点的 isWord 标记设为 true。
node->isWord = true;
return;
}
// 计算 word 中当前字符在 Trie 树中的下标。
int index = *word - 'a';
// 如果当前节点的 children 数组中没有对应的节点,则新建一个节点。
if (node->children[index] == NULL) {
node->children[index] = (struct TrieNode *)malloc(sizeof(struct TrieNode));
node->children[index]->c = *word;
node->children[index]->isWord = false;
memset(node->children[index]->children, 0, sizeof(node->children[index]->children));
}
// 递归插入下一个字符。
insert(node->children[index], word + 1);
}
bool search(struct TrieNode *node, const char *word, bool skip) {
if (*word == '\0') {
// 如果遇到了字符串的结尾,则检查当前节点的 isWord 标记是否为 true。
return node->isWord;
}
// 计算 word 中当前字符在 Trie 树中的下标。
int index = *word - 'a';
// 如果当前节点的 children 数组中没有对应的节点,则返回 false。
if (node->children[index] == NULL) {
return false;
}
// 如果 skip 为 true,则跳过当前字符继续匹配。
if (skip) {
return search(node->children[index], word + 1, false);
}
// 递归查找下一个字符。
return search(node->children[index], word + 1, false);
}
int main() {
// 初始化 Trie 树。
struct Trie trie;
trie.root = (struct TrieNode *)malloc(sizeof(struct TrieNode));
trie.root->c = '\0';
trie.root->isWord = false;
memset(trie.root->children, 0, sizeof(trie.root->children));
// 打开词典文件。
FILE *fp = fopen("dictionary.txt", "r");
if (fp == NULL) {
fprintf(stderr, "无法打开词典文件\n");
return 1;
}
// 读入词典中的单词,并将单词插入 Trie 树中。
char word[256];
while (fscanf(fp, "%s", word) != EOF) {
insert(trie.root, word);
}
fclose(fp);
// 读入要查找的单词。
while (scanf("%s", word) != EOF) {
// 在 Trie 树中查找单词。
if (search(trie.root, word, false)) {
printf("找到单词: %s\n", word);
} else if (search(trie.root, word, true)) {
printf("找到仅有一个字符不匹配的单词: %s\n", word);
} else {
printf("未找到单词: %s\n", word);
}
}
return 0;
}
字符串识别和匹配
从文件中把所有词典中的词读取到 放入到一个数组中,判断word在词典中的位置,就是通过循环一个个判断咯。
以下是详细解决代码,望采纳
#include <stdio.h>
#include <string.h>
#define WORD_LEN 256
// 定义词典中的单词
char words[100][WORD_LEN];
// 加载词典文件
void load_dictionary(const char* file_name)
{
// 打开词典文件
FILE* fp = fopen(file_name, "r");
if (fp == NULL)
{
printf("Error: Failed to open dictionary file.\n");
return;
}
// 读取词典文件中的所有单词
int i = 0;
while (fgets(words[i], WORD_LEN, fp) != NULL)
{
// 去除末尾的换行符
int len = strlen(words[i]);
if (words[i][len - 1] == '\n')
words[i][len - 1] = '\0';
i ++ ;
}
// 关闭词典文件
fclose(fp);
}
// 查找单词在词典中的位置
int find_word(const char* word)
{
for (int i = 0; i < 100; i ++ )
{
if (strcmp(words[i], word) == 0)
return i + 1; // 返回位置(从 1 开始)
}
return -1; // 未找到
}
// 查找词典中仅有一个字符与 word 不匹配的单词位置
int find_word_with_one_mismatch(const char* word)
{
for (int i = 0; i < 100; i ++ )
{
if (strlen(words[i]) != strlen(word)) continue; // 长度不同直接跳过
int mismatch = 0; // 不匹配的字符数
for (int j = 0; j < strlen(word); j ++ )
{
if (words[i][j] != word[j])
{
mismatch ++ ;
if (mismatch > 1) break;
}
}
if (mismatch == 1) return i + 1; // 返回位置(从 1 开始)
}
return -1; // 未找到
}
// 查找词典中比 word 多(或少)一个字符(除此字符外其余字符均匹配)的单词位置
int find_word_with_extra_char(const char* word)
{
for (int i = 0; i < 100; i ++ )
{
int len1 = strlen(words[i]);
int len2 = strlen(word);
if (abs(len1 - len2) != 1) continue; // 长度差不为 1 直接跳过
int extra = (len1 > len2) ? len1 - len2 : len2 - len1; // 差的字符数
int j = 0; // 指向 words[i] 的指针
int k = 0; // 指向 word 的指针
int mismatch = 0; // 不匹配的字符数
while (j < len1 && k < len2)
{
if (words[i][j] != word[k])
{
j ++ ;
extra -- ;
if (extra < 0) break; // words[i] 比 word 多了多余的字符,跳出循环
}
else
{
j ++ ;
k ++ ;
}
}
if (extra == 0) return i + 1; // 返回位置(从 1 开始)
}
return -1; // 未找到
}
int main()
{
// 加载词典文件
load_dictionary("dictionary.txt");
// 读入待查找的单词
char word[WORD_LEN];
printf("Enter a word to search: ");
scanf("%s", word);
// 查找单词在词典中的位置
int pos = find_word(word);
if (pos != -1)
printf("The word '%s' is found at position %d in the dictionary.\n", word, pos);
else
printf("The word '%s' is not found in the dictionary.\n", word);
// 查找词典中仅有一个字符与 word 不匹配的单词位置
pos = find_word_with_one_mismatch(word);
if (pos != -1)
printf("The word '%s' is found with one mismatch at position %d in the dictionary.\n", word, pos);
else
printf("The word '%s' is not found with one mismatch in the dictionary.\n", word);
// 查找词典中比 word 多(或少)一个字符(除此字符外其余字符均匹配)的单词位置
pos = find_word_with_extra_char(word);
if (pos != -1)
printf("The word '%s' is found with one extra character at position %d in the dictionary.\n", word, pos);
else
printf("The word '%s' is not found with one extra character in the dictionary.\n", word);
return 0;
}
为了解决这个问题,您可以考虑使用一种数据结构来存储词典,使得查找单词的操作具有较高的效率。具体来说,可以使用哈希表(hash table)或字典树(trie)来实现这个功能。
如果使用哈希表,可以将每个单词的每个字符的 ASCII 码值相加,然后对哈希表的大小取模来得到该单词在哈希表中的位置。这样,在词典中查找某个单词时,可以通过计算该单词的哈希值,然后在哈希表中快速定位到该单词。
如果使用字典树,则可以将每个单词插入到字典树中,并标记每个单词的结束位置。这样,在词典中查找某个单词时,可以从根节点开始,逐个比较单词中的字符,并跟随字典树的节点转移,直到找到符合条件的单词或者到达字典树的叶节点为止。
另外,还可以使用平衡树(例如红黑树)或者排序二分查找来实现这个功能,但是这些方法的效率通常略低于哈希表和字典树。
使用哈希表或字典树来实现单词匹配功能时,您需要编写代码来实现以下功能:
读入词典文件,将词典中的单词插入到哈希表或字典树中。
对于输入的单词 word,在哈希表或字典树中查找第⑴、⑵、⑶种情况的单词。对于第⑴种情况,可以直接计算 word 的哈希值或在字典树中查找 word;对于第⑵种情况,可以枚举 word 中的每个字符,并分别构造出与 word 只有一个字符不同的单词进行查找;对于第⑶种情况,可以枚举 word 中的每个字符,并分别构造出 word 多了一个字符或者少了一个字符的单词进行查找。
在查找到符合条件的单词后,输出找到的单词在词典中的位置以及该单词。如果未找到符合条件的单词,则输出提示信息。
在实现这些功能时,需要注意以下几点:
在使用哈希表时,要注意哈希冲突的问题。可以使用链地址法或开放地址法来解决冲突。
在使用字典树时,需要注意如何构造字典树的节点,以及如何实现插入、查找等操作。对于节点的构造,可以定义一个结构体,其中包含一个字符域和一个指针域。每个节点对应一个字符,指针域指向下一个字符的节点。当遇到单词的末尾时,将该节点标记为单词结束节点。
对于插入操作,可以从根节点开始,逐个比较单词中的字符,如果对应的节点已经存在,则跳转到下一个节点继续比较;如果不存在,则新建一个节点,并将该节点插入到对应的位置。
对于查找操作,可以从根节点开始,逐个比较单词中的字符,如果对应的节点已经存在,则跳转到下一个节点继续比较;如果不存在,则说明单词不存在。在查找过程中,如果遇到单词结束节点,则表示找到了单词。
需要注意的是,在使用字典树时,需要考虑如何处理多个单词共用一个前缀的情况。
在使用字典树时,如果有多个单词共用一个前缀,则可以将这些单词的公共前缀放在一个节点上,并在这个节点的指针域中存储每个字符对应的节点。这样,在查找单词时,就可以直接从公共前缀的节点开始查找,而不需要从根节点开始。
举个例子,如果词典中有单词 "book"、"books" 和 "bookcase",则可以将它们插入到字典树中,如下图所示:
b o o k s e c a s e
| | | | | | | | | |
root b o o k s e c a s e
在查找单词时,如果要查找 "book",则可以直接从 "b" 节点开始查找;如果要查找 "books",则可以直接从 "s" 节点开始查找;如果要查找 "bookcase",则可以直接从 "c" 节点开始查找。
希望以上内容能够对您有帮助。
用Trie 树做吧,简单
替换单词c语言程序,用c语言完成单词替换
借鉴下
https://blog.csdn.net/weixin_34293588/article/details/117052330