[问题描述]
利用键树结构,建立一个微型电子字典。
[基本要求]
实现生词的加入,单词的查找、删除,修改等操作。
[基本思路]
这道题的关键就是键树的操作,键树大概就是下图的样子,每个节点存一个字母,多个节点相连构成一个单词,单词的最后一个字母的节点再存储汉译,并用一个bool记这是个单词的结尾。
[代码实现]
头文件即节点声明
#include<iostream>
#include<fstream>
using namespace std;
typedef struct node
{
bool is_word;//记录是否是单词的尾字母
char data;//当前节点数据
string translation;//汉译
node* next[26];//子节点指针,a~z的顺序
int num;//子结点个数
node()//构造函数
{
memset(next, NULL, sizeof(next));
num = 0;
is_word = false;
}
}node;
node* root = new node;//根节点声明
单词添加
void add(string tran, string s, node* t, int d)
{
if (t->next[int(s[d] - 'a')] == NULL)//该节点子节点字符没有与所添加单词下一字母相同的
{
t->next[int(s[d] - 'a')] = new node;//新建节点
t->next[int(s[d] - 'a')]->data = s[d];
if (d == s.length() - 1)//单词存储完成
{
t->next[int(s[d] - 'a')]->is_word = true;
t->next[int(s[d] - 'a')]->translation = tran;
cout << tran << endl;
t->num++;
return;
}
t->num++;
add(tran, s, t->next[int(s[d] - 'a')], d + 1);
}
else//有相同的
{
if (d == s.length() - 1)//单词存储完成
{
t->next[int(s[d] - 'a')]->is_word = true;
t->next[int(s[d] - 'a')]->translation = tran;
cout << tran << endl;
return;
}
add(tran, s, t->next[int(s[d] - 'a')], d + 1);
}
}
单词删除
bool delete_(string s, node* t, int d)
{
if (d == s.length())
{
t->is_word = false;
if (t->num == 0)//该节点无子节点
{
return true;
}
return false;
}
else
{
if (delete_(s, t->next[int(s[d] - 'a')], d + 1))//若末节点删除,则删除其在上一节点对应的信息
{
free(t->next[int(s[d] - 'a')]);
t->next[int(s[d] - 'a')] = NULL;
if (t->is_word)//若当前节点
return false;
t->num--;
if (t->num == 0)//若当前节点仍有其他子节点,保留
return true;
else
return false;
}
else//否则上节点无变化
{
return false;
}
}
}
单词查找
bool search(string s,node *t,int d,bool flag)
{
static char out[100] = { '\0' };
if (d == s.length())
{
if (t->is_word == true)
{
if (flag)
{
for (int i = 0; i <= d; i++)
cout << out[i];
cout << ' ' << t->translation;
cout << endl;
}
return true;
}
else
return false;
}
if (t->next[int(s[d] - 'a')] == NULL)
{
return false;
}
else
{
return search(s, t->next[int(s[d] - 'a')], d + 1, flag);
}
}
单词展示
void show(node *t,int d)
{
static char s[32] = { 0 };
if (d != -1)
s[d] = t->data;
if (t->is_word)
{
for (int i = 0; i <= d; i++)
cout << s[i];
cout << ' ' << t->translation << endl;
}
for (int i = 0; i < 26; i++)
{
if (t->next[i] != NULL)
show(t->next[i], d + 1);
}
return;
}
单词存储(单词添加可以直接在文件尾追加,没必要用这个函数,主要是删除)
void sort(node* t, int d)
{
fstream file("word.txt", ios::app);
static char s[100] = { '\0' };
if (d != -1)
s[d] = t->data;
else
{
fill(s, s + 100, '\0');
}
if (t->is_word)
{
for (int i = 0; i <= d; i++)
file << s[i];
file << ' ';
file << t->translation;
file << '\n';
file.flush();
}
for (int i = 0; i < 26; i++)
{
if (t->next[i] != NULL)
sort(t->next[i], d + 1);
}
file.flush();
}
源代码
#include<iostream>
#include<fstream>
using namespace std;
typedef struct node
{
bool is_word;//记录是否是单词的尾字母
char data;//当前节点数据
string translation;//汉译
node* next[26];//子节点指针
int num;//子结点个数
node()//构造函数
{
memset(next, NULL, sizeof(next));
num = 0;
is_word = false;
}
}node;
node* root = new node;//根节点声明
bool is_lawful(string s)
{
int i = 0;
while (s[i] != '\0')
{
if (s[i] > 'z' || s[i] < 'a')
return false;
i++;
}
return true;
}
void add(string tran, string s, node* t, int d)
{
if (t->next[int(s[d] - 'a')] == NULL)//该节点子节点字符没有与所添加单词下一字母相同的
{
t->next[int(s[d] - 'a')] = new node;//新建节点
t->next[int(s[d] - 'a')]->data = s[d];
if (d == s.length() - 1)//单词存储完成
{
t->next[int(s[d] - 'a')]->is_word = true;
t->next[int(s[d] - 'a')]->translation = tran;
//cout << tran << endl;
t->num++;
return;
}
t->num++;
add(tran, s, t->next[int(s[d] - 'a')], d + 1);
}
else//有相同的
{
if (d == s.length() - 1)//单词存储完成
{
t->next[int(s[d] - 'a')]->is_word = true;
t->next[int(s[d] - 'a')]->translation = tran;
//cout << tran << endl;
return;
}
add(tran, s, t->next[int(s[d] - 'a')], d + 1);
}
}
bool delete_(string s, node* t, int d)
{
if (d == s.length())
{
t->is_word = false;
if (t->num == 0)//该节点无子节点
{
return true;
}
return false;
}
else
{
if (delete_(s, t->next[int(s[d] - 'a')], d + 1))//若末节点删除,则删除其在上一节点对应的信息
{
free(t->next[int(s[d] - 'a')]);
t->next[int(s[d] - 'a')] = NULL;
if (t->is_word)
return false;
t->num--;
if (t->num == 0)
return true;
else
return false;
}
else//否则上节点无变化
{
return false;
}
}
}
void initialize()
{
fstream file("word.txt", ios::in);
if (file.fail())
{
cout << "word.txt打开失败!!!" << endl;
exit(0);
}
while (!file.eof())
{
string s;
string tran;
file >> s;
file >> tran;
//cout << s << endl;
if (s != "")
add(tran, s, root, 0);
}
}
bool search(string s,node *t,int d,bool flag)
{
static char out[100] = { '\0' };
if (d == s.length())
{
if (t->is_word == true)
{
if (flag)
{
for (int i = 0; i <= d; i++)
cout << out[i];
cout << ' ' << t->translation;
cout << endl;
}
return true;
}
else
return false;
}
if (t->next[int(s[d] - 'a')] == NULL)
{
return false;
}
else
{
return search(s, t->next[int(s[d] - 'a')], d + 1, flag);
}
}
void show(node *t,int d)
{
static char s[32] = { 0 };
if (d != -1)
s[d] = t->data;
if (t->is_word)
{
for (int i = 0; i <= d; i++)
cout << s[i];
cout << ' ' << t->translation << endl;
}
for (int i = 0; i < 26; i++)
{
if (t->next[i] != NULL)
show(t->next[i], d + 1);
}
return;
}
void sort(node* t, int d)
{
fstream file("word.txt", ios::app);
static char s[100] = { '\0' };
if (d != -1)
s[d] = t->data;
else
{
fill(s, s + 100, '\0');
}
if (t->is_word)
{
for (int i = 0; i <= d; i++)
file << s[i];
file << ' ';
file << t->translation;
file << '\n';
file.flush();
}
for (int i = 0; i < 26; i++)
{
if (t->next[i] != NULL)
sort(t->next[i], d + 1);
}
file.flush();
}
void run()
{
while (1)
{
cout << "1.添加单词" << endl << "2.查找单词" << endl << "3.删除单词" << endl << "4.修改单词" << endl;
cout << "5.单词展示" << endl << "6.退出程序" << endl;
int choice;
cin >> choice;
switch (choice)
{
case 1: {
string s;
string tran;
cout << "请输入单词:";
cin >> s;
cout << "请输入汉译:";
cin >> tran;
if (!is_lawful(s))
{
cout << "输入不合法!!!" << endl;
system("pause");
system("cls");
break;
}
if (search(s, root, 0, false))
{
cout << "单词已存在!!!" << endl;
system("pause");
system("cls");
break;
}
fstream file("word.txt", ios::app);
if (file.fail())
{
cout << "word.txt打开失败!!!" << endl;
exit(0);
}
file << s << ' ' << tran << '\n';
file.close();
add(tran, s, root, 0);
cout << "添加成功!!!" << endl;
system("pause");
system("cls");
break;
}
case 2: {
cout << "请输入要查找的单词:";
string s;
cin >> s;
if (!is_lawful(s))
{
cout << "输入不合法!!!" << endl;
system("pause");
system("cls");
break;
}
if (search(s, root, 0, true))
{
cout << "单词存在。" << endl;
}
else
{
cout << "未找到!!!" << endl;
}
system("pause");
system("cls");
break;
}
case 3: {
string s;
cout << "请输入要删除的单词:";
cin >> s;
if (!is_lawful(s))
{
cout << "输入不合法!!!" << endl;
system("pause");
system("cls");
break;
}
if (!search(s, root, 0, false))
{
cout << "单词不存在!!!" << endl;
system("pause");
system("cls");
break;
}
delete_(s,root,0);
fstream file("word.txt", ios::trunc | ios::out);
sort(root, -1);
file.close();
cout << "删除成功!!!" << endl;
system("pause");
system("cls");
break;
}
case 4: {
string s1, s2;
while (1)
{
cout << "请输入要修改的单词:";
cin >> s1;
if (!is_lawful(s1))
{
cout << "输入不合法!!!" << endl;
system("pause");
system("cls");
continue;
}
if (!search(s1, root, 0, false))
{
cout << "单词不存在!!!" << endl;
system("pause");
system("cls");
continue;
}
break;
}
string tran;
while (1)
{
cout << "请输入写改成什么单词:";
cin >> s2;
cout << "汉译:";
cin >> tran;
if (!is_lawful(s2))
{
cout << "输入不合法!!!" << endl;
system("pause");
system("cls");
continue;
}
break;
}
delete_(s1, root, 0);
add(tran, s2, root, 0);
fstream file("word.txt", ios::trunc | ios::out);
sort(root, -1);
file.close();
cout << "修改成功!!!" << endl;
system("pause");
system("cls");
break;
}
case 5: {
show(root, -1);
system("pause");
system("cls");
break;
}
case 6: {
return;
}
}
}
}
int main()
{
initialize();
run();
return 0;
}
[运行结果]