找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 689|回复: 3

【C】离线英英词典

[复制链接]
发表于 2023-1-23 02:00:55 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
本帖最后由 usr 于 2023-1-23 02:02 编辑

这是一款离线英英词典。该词典具有小内存占用和极高的查询速度。
原理很简单,搜索TXT格式的文件。把所有单词INDEX后装入内存。
源代码在这里:(注意该词典需要StoneValley库的支持)
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "StoneValley/src/svset.h"
  6. #include "StoneValley/src/svtree.h"

  7. typedef struct st_WORD
  8. {
  9.         ptrdiff_t id;
  10.         char name[64];
  11.         size_t times;
  12.         long ltip;
  13. } WORD, * P_WORD;

  14. int cbfcmpid(const void * px, const void * py)
  15. {
  16.         return (*(P_WORD)px).id - (*(P_WORD)py).id;
  17. }

  18. int cbfcmpchar(const void * px, const void * py)
  19. {
  20.         return *(char *)px - *(char *)py;
  21. }

  22. int cbftvs_history(void * pitem, size_t param)
  23. {
  24.         if (((P_WORD)P2P_TNODE_B(pitem)->pdata)->times)
  25.                 printf("%s\t%lld\n", ((P_WORD)P2P_TNODE_B(pitem)->pdata)->name, ((P_WORD)P2P_TNODE_B(pitem)->pdata)->times);
  26.         return CBF_CONTINUE;
  27. }

  28. int cbftvs_alphabet(void * pitem, size_t param)
  29. {
  30.         if (toupper(((P_WORD)P2P_TNODE_B(pitem)->pdata)->name[0]) == param)
  31.                 printf("%s\n", ((P_WORD)P2P_TNODE_B(pitem)->pdata)->name);
  32.         return CBF_CONTINUE;
  33. }

  34. static char sWord[BUFSIZ * 2] = { 0 };
  35. static char * p = sWord;

  36. static char sFileName[BUFSIZ] = { 0 };
  37. static char sPattern[BUFSIZ] = { 0 };

  38. int main(int argc, char ** argv)
  39. {
  40.         size_t i = 1, j;
  41.         WORD w = { 0 };
  42.         FILE * fp;
  43.         P_SET_T set = setCreateT();
  44.         P_TRIE_A trie = treCreateTrieA();
  45.         size_t * result = NULL;

  46.         strcat(sFileName, ".\\dict.txt");
  47.         fp = fopen(sFileName, "rb");


  48.         printf("Dict file: %s\n", sFileName);
  49.         if (NULL != fp)
  50.         {
  51.                 while (!feof(fp))
  52.                 {
  53.                         *p = fgetc(fp);
  54.                         ++p;
  55.                         if ('#' == *(p - 1))
  56.                         {
  57.                                 P_BSTNODE pnode = NULL;
  58.                                 *(p - 1) = '\0';
  59.                                 p = sWord;

  60.                                 strcpy(w.name, p);
  61.                                 w.id = i;
  62.                                 w.times = 0;
  63.                                 w.ltip = ftell(fp) + 1;

  64.                                 setInsertT(set, &w, sizeof w, cbfcmpid);
  65.                                 pnode = treBSTFindData_A(*set, &i, cbfcmpid);
  66.                                 treInsertTrieA(trie, p, strlen(p), sizeof(char), (size_t)(pnode->knot.pdata), cbfcmpchar);

  67.                                 ++i;
  68.                         }
  69.                         if ('\n' == *(p - 1))
  70.                         {
  71.                                 p = sWord;
  72.                         }
  73.                 }
  74.                 printf("%lld words loaded.\n", i);
  75.                 do
  76.                 {
  77.                         printf("? ");
  78.                         fgets(sPattern, 100, stdin);
  79.                         sPattern[strlen(sPattern) - 1] = '\0';
  80.                         if ('\0' == *sPattern)
  81.                                 break;
  82.                         printf("Searching: "%s"...\n", sPattern);
  83.                         result = treSearchTrieA(trie, sPattern, strlen(sPattern), sizeof(char), cbfcmpchar);
  84.                         if (result)
  85.                         {
  86.                                 printf("\t%lld %s  ", ((P_WORD)*result)->id, ((P_WORD)*result)->name);
  87.                                 ++((P_WORD)*result)->times;

  88.                                 /* Redirect to the word on the disk. */
  89.                                 fseek(fp, ((P_WORD)*result)->ltip, SEEK_SET);
  90.                                 /* Read explanations. */
  91.                                 p = sWord;
  92.                                 while ('\n' != (*p = fgetc(fp)))
  93.                                 {
  94.                                         ++p;
  95.                                 }
  96.                                 *p = '\0';
  97.                                 p = sWord;
  98.                                 printf("\t%s\n", p);
  99.                         }
  100.                         else if ('.' == sPattern[0] && '?' == sPattern[1])
  101.                         {
  102.                                 printf("Type [WORD] or [NUMBER] to search.\n");
  103.                                 printf("\tFor example ? Apple ? 10536\n");
  104.                                 printf("Type .h to show history.\n");
  105.                                 printf("Type .l[A] to show alphabet.\n");
  106.                                 printf("\tFor example ? .l Z.\n");
  107.                                 printf("Type .? to show this notice.\n");
  108.                         }
  109.                         else if ('.' == sPattern[0] && 'h' == sPattern[1])
  110.                         {
  111.                                 printf("History:\n");
  112.                                 treTraverseBIn(*set, cbftvs_history, 0);
  113.                         }
  114.                         else if ('.' == sPattern[0] && 'l' == sPattern[1] && ' ' == sPattern[2])
  115.                         {
  116.                                 sPattern[3] = toupper(sPattern[3]);
  117.                                 printf("Alphabet:\n");
  118.                                 treTraverseBIn(*set, cbftvs_alphabet, toupper(sPattern[3]));
  119.                         }
  120.                         else if (0 != (j = atoi(sPattern)))
  121.                         {
  122.                                 P_BSTNODE pnode = treBSTFindData_A(*set, &j, cbfcmpid);
  123.                                 if (pnode)
  124.                                 {
  125.                                         printf("\t%lld %s  ", ((P_WORD)(pnode->knot.pdata))->id, ((P_WORD)(pnode->knot.pdata))->name);
  126.                                         ++((P_WORD)(pnode->knot.pdata))->times;

  127.                                         /* Redirect to the word on the disk. */
  128.                                         fseek(fp, ((P_WORD)(pnode->knot.pdata))->ltip, SEEK_SET);
  129.                                         /* Read explanations. */
  130.                                         p = sWord;
  131.                                         while ('\n' != (*p = fgetc(fp)))
  132.                                         {
  133.                                                 ++p;
  134.                                         }
  135.                                         *p = '\0';
  136.                                         p = sWord;
  137.                                         printf("\t%s\n", p);
  138.                                 }
  139.                         }
  140.                         else
  141.                         {
  142.                                 printf("Can not find "%s".\n", sPattern);
  143.                         }
  144.                 } while ('\0' != sPattern[0]);
  145.                 fclose(fp);
  146.         }
  147.         else
  148.                 printf("Can not open file.\n");

  149.         printf("History:\n");
  150.         treTraverseBIn(*set, cbftvs_history, 0);
  151.         setDeleteT(set);
  152.         treDeleteTrieA(trie, sizeof(char));
  153.         return 0;
  154. }
复制代码

运行截图如下:
Screenshot 2023-01-23 014707.png
Screenshot 2023-01-23 014752.png
这是词典的源码:欢迎下载
Dict.zip (1.9 MB, 下载次数: 3, 售价: 5 个宅币)
具体原理是将词典中的单词放在了平衡二叉搜索树和Trie树当中以方便查询。
回复

使用道具 举报

发表于 2023-1-24 01:35:01 | 显示全部楼层
建议尝试脱离 StoneValley 库,看看能不能自己写出类似的算法,通过给定 index 进行快速的查询?
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2023-1-25 14:53:13 | 显示全部楼层
0xAA55 发表于 2023-1-24 01:35
建议尝试脱离 StoneValley 库,看看能不能自己写出类似的算法,通过给定 index 进行快速的查询? ...

好的我试试看,但是离开SV库也只是在重复造轮子啊。会又写一个差不多的搜索树。
回复 赞! 靠!

使用道具 举报

发表于 2023-1-27 01:31:32 | 显示全部楼层
usr 发表于 2023-1-25 14:53
好的我试试看,但是离开SV库也只是在重复造轮子啊。会又写一个差不多的搜索树。 ...

如果不是以工作用为目标,而是以学习算法和数据结构为目标,那造轮子是很好的学习方式,是一定要试试的。
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-21 22:18 , Processed in 0.039550 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表