单词匹配 c语言编程,求解

单词匹配
已知一个包含若干英文单词的词典(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>

img

#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