实现字典小代码--软件工程思想

本文介绍如何通过链表结构存储字典文件,并利用单词索引减少内存消耗。通过优化代码,仅存储单词及其对应索引,提高查找效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需要的文件在我的主页,可以买免费下载

题意:

将一个字典文件存到链表中,在程序中输入一个英文单词,查询该输入单词的意思:

步骤:

1、将文件解析存到链表中

在这里插入图片描述

2、查找单词

在这里插入图片描述

3、释放内存

在这里插入图片描述

4、文件内容

在这里插入图片描述

代码实现

s思想:

创建一个链表,使用结构体,具有一个work, trans, next的指针,分别存储文件中的单词、单词的意思、指向下一个节点

然后输入一个单词,查找到这个单词,输出这个单词的意思就可以了

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>

#define LEN 2048
typedef struct Node {
    char *word;
    char *trans;
    struct Node *next;
}Node;

/*
 * 使用的是链表
 */
Node *loadDict(Node *head) {
    char buff[LEN];
    FILE *fp = fopen("./dict_e2c.txt", "r");
    if (!fp) {
        perror("open dict_e2c.txt file");
        exit(1);
    }
    while(fgets(buff,LEN,fp)) {//读取文件, 一行一行的读取
        Node *nn = (Node *)malloc(sizeof(Node));//创建一个新的节点
        /*先读取第一行存的是单词*/
        nn->word = (char *)malloc(sizeof(char)*(strlen(buff) + 1));
        strcpy(nn->word, buff + 1);//buff[1]开始的位置复制到nn->word这个数组里面
        nn->word[strlen(nn->word) - 1] = '\0';
      /*读取第二行,存的是解释*/
        fgets(buff,LEN,fp) ;
        nn -> trans = (char *)malloc(sizeof(char)*(strlen(buff) + 1));
        strcpy(nn->trans, buff + 6);
         //buff[1]开始的位置复制到nn->word这个数组里面,我们的文件案例前面多了Trans: --> 所以从第六个开始
        nn -> word[strlen(nn->word) - 1] = '\0';
        //头插法
        nn->next = head;
        head = nn;

    }
    fclose(fp);
    return head;
}
/*
 *查找单词
 */
Node * findTrans(Node *head, char *iptwd) {
    // char iptwd[100] 相当于char *iptwd,指针来的
    Node *p = head;

   while (p && strcmp(iptwd, p->word)) { //strcmp相等时返回0
      p = p -> next;
   }
   return p;
}

void freeSys(Node *head) {
    Node *p = head;
    Node *k;
    while(p) {
        k = p;
        p  = p -> next;
        free(k -> word);
        free(k -> trans);
        free(k -> next);
        free(k);
    }
    return ;
}

int main(void){
    Node *head = NULL;

    head = loadDict(head);//要设置返回值

    char iptwd[100];//读取字符,查找单词

    while(1) {
        printf("please input a word: ");
        scanf("%s", iptwd);
        if(!strcmp(iptwd, "__quit")) {//相同的话返回值为0, 输入字符串 __quit退出程序
            break;
        }
        Node *tmp =  findTrans(head, iptwd);//查找单词的操作
        if(tmp)
          printf("%s",tmp->trans);
        else
          printf("your word not found^_^!\n");
    }
    printf("see you~~~\n");
    freeSys(head);//释放系统
    return 0;
}

代码优化:

上面的写法太浪费空间,我们可以存储一个序号,就是单词的序号,这样子就可以就不用创建一个属于trans的空间了,当我们查找到这个单词的时候,输出相应序号对应的解释就好了

	#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>

#define LEN 2048

typedef struct Node {
    char *word;
    //char *trans;
    int idx; //索引
    struct Node *next;
}Node;

/*
 * 使用的是链表
 */
Node *loadDict(Node *head) {
    char buff[LEN];

    FILE *fp = fopen("./dict_e2c.txt", "r");
    if (!fp) {
        perror("open dict_e2c.txt file");
        exit(1);
    }
    while(fgets(buff,LEN,fp)) {//读取文件
        Node *nn = (Node *)malloc(sizeof(Node));//创建一个新的节点

        /*先读取第一行存的是单词*/
        nn->word = (char *)malloc(sizeof(char)*(strlen(buff) + 1));
        strcpy(nn->word, buff + 1);//buff[1]开始的位置复制到nn->word这个数组里面
        nn->word[strlen(nn->word) - 1] = '\0';
        nn -> idx = ftell(fp);//存下索引的位置

       // fgets(buff,LEN,fp) ;//读取buff中内容
       //  nn -> trans = (char *)malloc(sizeof(char)*(strlen(buff) + 1));
       // strcpy(nn->trans, buff + 6);//buff[1]开始的位置复制到nn->word这个数组里面
        //nn -> word[strlen(nn->word) - 1] = '\0';
        //头插法
        nn->next = head;
        head = nn;
    }
    fclose(fp);
    return head;
}
/*
 *查找单词
 */
Node * findTrans(Node *head, char *iptwd) {
    // char iptwd[100] 相当于char *iptwd,指针来的
    Node *p = head;
    while (p && strcmp(iptwd, p->word)) { //strcmp相等时返回0
       p = p -> next;
    }
    return p;
}

void freeSys(Node *head) {
    Node *p = head;
    Node *k;
    while(p) {
        k = p;
        p  = p -> next;
        free(k -> word);
      //  free(k -> trans);
        free(k -> next);
        free(k);
    }
    return ;
}

int main(void){
    Node *head = NULL;
    head = loadDict(head);//要设置返回值
    char iptwd[100];//读取字符,查找单词
    char buff[LEN];
    FILE *fp = fopen("./dict_e2c.txt", "r");
    if (!fp) {
        perror("open dict_e2c.txt file");
        exit(1);
    }
    while(1) {
        printf("please input a word: ");
        scanf("%s", iptwd);
        if(!strcmp(iptwd, "__quit")) {//相同的话返回值为0
            break;
        }
        Node *tmp =  findTrans(head, iptwd);//查找单词的操作
        if(tmp){
        //  printf("%s",tmp->trans);
          fseek(fp, tmp -> idx, SEEK_SET);//设置指针到idx的位置
          fgets(buff, LEN,fp);//解释存入buff数组中
          printf("%s", buff);
        }  else
          printf("your word not found^_^!\n");
    }
    fclose(fp);
    printf("see you~~~\n");
    freeSys(head);//释放系统
    return 0;
}

      fgets(buff, LEN,fp);//解释存入buff数组中
      printf("%s", buff);
    }  else
      printf("your word not found^_^!\n");
}
fclose(fp);
printf("see you~~~\n");
freeSys(head);//释放系统
return 0;

}

> 写于2021-08-20
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值