电子小字典(键树)

电子小字典(查找)

[问题描述]

利用键树结构,建立一个微型电子字典。

[基本要求]

实现生词的加入,单词的查找、删除,修改等操作。

解题思路:

首先对键树结构进行解释。这里,我们每个节点中并不是一个或几个关键字,而是只含有组成关键字的符号。在这题中,每个节点只包含组成单词的字母。我们用结构体数组(vector类型)来存储键树,原键树的节点在这里对应数组的一格。先在“字典”中初始化26个英文字母(小写),作为插入、查询等的起始位置。

插入:对要插入单词的字母进行逐个遍历,先匹配字典中已有的部分,例如原来已有“be”,再插入“bean”时,就会先匹配be的部分,之后an的部分会在vector后面按顺序添加,最后将末尾字母的end置为1,代表一个单词插入完成。查询时,按照next进行追踪即可。删除:先查询,若查询成功,则获得末尾字母的编号,把末尾字母的end重新置为0,则删除成功;若查询失败,则插入失败。修改:考虑到修改的方式多种多样,可能是减短、增长或改变几个字母等,为了简便,这里就直接把原单词删除,再把修改后的单词插入到字典中。

程序代码:

# include <iostream>
# include <stdlib.h>
# include <string>
# include <vector>

using namespace std;

typedef struct Alphabet {
    char a;     //字母
    int end;    //是否为单词结尾(0:否 1:是)
    vector<int>next;
}Alphabet;

//操作菜单
void Menu();
//添加单词
void InsertWord(string str);
//查询单词
int SearchWord(string str);
//删除单词
void DeleteWord(string str);
//修改单词
void ChangeWord(string str1, string str);
int num = 0;          //保存当前的数组长度
vector<Alphabet>word; //字典

//主函数
int main()
{
    //初始化字典
    Alphabet al;
    for (int i = 0; i < 26; i++) {
        al.a = 97 + i;
        al.end = 0;
        word.push_back(al);
        num++;
    }
    int select;
    while (1) {
        int t;
        string str, str1;
        Menu();
        cout << "请选择:";
        cin >> select;
        if (select == 1) {
            //添加单词
            cout << "请输入要添加的单词:";
            cin >> str;
            InsertWord(str);
        }
        else if (select == 2) {
            //查询单词
            cout << "请输入要查询的单词:";
            cin >> str;
            t = SearchWord(str);
            if (t >= 0) {
                cout << "查询成功" << endl;
            }
            else {
                cout << "查询失败" << endl;
            }
        }
        else if (select == 3) {
            //删除单词
            cout << "请输入要删除的单词:";
            cin >> str;
            DeleteWord(str);
        }
        else if (select == 4) {
            //修改单词
            cout << "请输入要修改的单词:";
            cin >> str1;
            cout << "请输入修改后的单词:";
            cin >> str;
            ChangeWord(str1, str);
        }
        else {
            break;
        }
    }
    return 0;
}

//操作菜单
void Menu()
{
    cout << "\n*******************************\n";
    cout << "**(1)、添加单词 *************\n";
    cout << "**(2)、查询单词 *************\n";
    cout << "**(3)、删除单词 *************\n";
    cout << "**(4)、修改单词 *************\n";
    cout << "**(5)、退出 *****************\n";
    cout << "*******************************\n";
}

//添加单词
void InsertWord(string str)
{
    Alphabet al;
    int j = str[0] - 97;  //字母
    int t, i;
    for (i = 1; i < str.size(); i++) {
        t = 0;
        for (int k = 0; k < word[j].next.size(); k++) {
            int m = word[j].next[k];
            if (word[m].a == str[i]) {
                j = m;
                t = 1;
                break;
            }
        }
        if (!t) {
            //到此能遍历的单词部分
            break;
        }
    }
    while (i < str.size()) {
        //单词没有遍历完
        al.a = str[i];
        al.end = 0;
        word[j].next.push_back(num);
        word.push_back(al);
        j = num;
        num++;
        i++;
    }
    word[j].end = 1;
}

//查询单词
int SearchWord(string str)
{
    int j = str[0] - 97;  //字母
    int t, i;
    for (i = 1; i < str.size(); i++) {
        t = 0;
        for (int k = 0; k < word[j].next.size(); k++) {
            int m = word[j].next[k];
            if (word[m].a == str[i]) {
                j = m;
                t = 1;
                break;
            }
        }
        if (!t) {
            //到此能遍历的单词部分
            break;
        }
    }
    if (i == str.size() && word[j].end) {
        return j;
    }
    else {
        return -1;
    }
}

//删除单词
void DeleteWord(string str)
{
    int t = SearchWord(str);
    if (t >= 0) {
        word[t].end = 0;
        cout << "删除成功" << endl;
    }
    else {
        cout << "删除失败" << endl;
    }
}

//修改单词
void ChangeWord(string str1, string str)
{
    int t = SearchWord(str1);
    if (t >= 0) {
        word[t].end = 0;
        InsertWord(str);
        cout << "修改成功" << endl;
    }
    else {
        cout << "修改失败" << endl;
    }
}

总结:

这种写法比较简单,但也有一定的缺点。对于单词的删除,我只是做了形式上的“删除”,保证其无法再被查询到,但其占据的空间还在,这样会导致空间的浪费。大家可以尝试自己改进。

以上是我对这道题的看法,很高兴与大家分享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值