一、实验题目及要求

题目:英汉翻译小词典

需求:

1、根据所提供的词典http://github.com/1eez/103976建立英文词典;

2、任意输入单词,判断该单词是否在词典中,输出查找结果,同时输入单词匹配过程中对比的中间关键字;

3、模仿Google的搜索界面,根据用户输入实时显示备选词。

二、概要设计

本次实验所用的数据结构为二叉搜索树BST,BST树具有以下特点:左子树上所有结点的值均小于或等于它的根结点的值;右子树上所有结点的值均大于或等于它的根结点的值;左、右子树也分别为二叉排序树。如果使用BST树将数据组织起来,树的每个结点都包含了健值 key、数据值 data、左子女指针、右子女指针。其中键值 key 是最核心的部分,它的值决定了树的组织形状;左子节点指针指向左子节点;右子节点指针指向右子节点;数据值 data 是该结点对应的数据,可以根据键值key找到数据data,因此适用于词典中单词的存储。

设计了两种建树的方法,分别为常规方法和折半方法;对BST树的操作有插入结点和搜索结点。使用Qt进行窗口交互设计,在widget.h中,widget实现的功能有读取csv文件、顺序方法搜索查找和BST搜索查找;用两个QStringList来分别存储英语单词和释义,方便QCompleter的使用,接收顺序输入序列时,采用折半思想,先问左侧数据,再访问右侧数据,以此递归。

由于英文词典中存在汉字字符,所以必须解决中文乱码问题。在使用 QTextStream 读写有中文内容的文本文件时,为了能正确识别 Unicode 码,需要调用 setAutoDetectUnicode(true),设置 QTextStream 可以自动识别 Unicode 码,如果不做此设置,读取文件的中文将是乱码,无法正常显示。为解决 Unicode 的识别问题,可以在应用程序中做全局的设置,使得应用程序支持 Unicode,方法是在 main() 函数中使用 QTextCodec 类进行编码设置。在本次实验中,在main()函数中添加语句
QTextCodec *codec=QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForLocale(codec);
这样就设置了应用程序使用的编码解码器,在应用程序内就有了对 Unicode 码的支持。在前面的 openTextByStream() 函数中,即使不用 setAutoDetectUnicode(true) 也可以正常显示汉字了。
三、详细设计
在BST结点类中定义了QString类型的data和BSTNode*类型的left和right,分别为左孩子指针和右孩子指针;在BST树类中定义了BSTNode类型的根节点root指针,并有Insert、Build1、Build2三个函数成员,分别执行插入节点、常规方法建树和折半方法建树操作。
struct BSTNode
{QString data;BSTNode *left,*right;//构造函数BSTNode():left(NULL),right(NULL){}BSTNode(QString str,BSTNode *l=NULL,BSTNode *r=NULL):data(str),left(l),right(r){}//析构函数~BSTNode(){}
};class BST
{
public:BSTNode *root;//构造和析构BST():root(NULL){}BST(BSTNode *r):root(r){}~BST(){}bool Insert(QString str,BSTNode *&rootPtr);//插入结点bool Build1(QVector<QString> v);//常规方法建树bool Build2(QVector<QString> v);//折半方法建树BSTNode* Search(QString str,BSTNode *rootPtr,int &amount);//搜索结点
};
插入结点操作,如果rootPtr指针为空,就用new关键字动态分配内存空间;否则如果str小于rootPtr的data,就递归地调用Insert函数插入左子女,如果str大于rootPtr的data,就递归地调用Insert函数插入右子女。
bool BST::Insert(QString str,BSTNode *&rootPtr)
{if(rootPtr==NULL){rootPtr=new BSTNode(str);if(rootPtr==NULL)qDebug()<<"错误!";return true; }else if(str<rootPtr->data)Insert(str,rootPtr->left);else if(str>rootPtr->data)Insert(str,rootPtr->right);elsereturn false;//结点已存在
}

常规方法建立BST树,如果动态数组v的大小为0,返回false;否则采用for循环调用Insert函数依次插入每个结点。

bool BST::Build1(QVector<QString> v)
{if(v.size()==0)return false;for(int i=0;i<v.size();i++)Insert(v.at(i),root);return true;
}

折半方法建立BST树,设置变量mid值为v的大小的一半,分别在左侧和右侧序列进行插入。

bool BST::Build2(QVector<QString> v)
{if (v.size() == 0)return false;int mid;mid = v.size() / 2;Insert(v[mid], root);QVector<QString> pre = v;for (int i = 0; i < v.size() - mid; i++){QVector<QString>::iterator pEnd = pre.end();pre.erase(--pEnd);//折半左侧序列}Build2(pre);QVector<QString> post = v;for (int i = 0; i < mid + 1; i++){QVector<QString>::iterator pBegin = post.begin();post.erase(pBegin);//折半右侧序列}Build2(post);
}

搜索结点操作,设置BSTNode*类型工作指针temp,初始值赋为rootPtr,在while循环中,用int类型的pos指示位置信息;在for循环中,如果出现temp->data.at(i)==' '就把i的值赋给pos,再定义字符串s,赋值为temp->data.mid(0, pos),将str与s进行比较,如果str较小,temp就指向左孩子,如果str较大,temp就指向右孩子,如果相等就返回temp,从而完成搜索结点操作。

BSTNode* BST::Search(QString str,BSTNode* rootPtr,int &amount)
{BSTNode* temp = new BSTNode;temp = rootPtr;while (temp != NULL){int pos=0;for(int i=0;i<temp->data.size();i++){if(temp->data.at(i)==' '){pos=i;break;}}QString s = temp->data.mid(0, pos);qDebug()<<s;amount++;if (str < s)temp = temp->left;else if (str > s)temp = temp->right;elsereturn temp;}return NULL;
}
ui界面已设置显示文本框read_only,按钮及文本框字体已设置;用两个QStringList来分别存储英语单词和释义,方便QCompleter的使用;在接收顺序输入序列时,先输入最中间数据,再访问左侧数据,再访问右侧数据,并以此递归。在widget.cpp中,先读取csv文件,之后实现搜索框下拉选项显示,之后把单词表和翻译表合并,方便BST搜索。
Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);setFixedSize(420,680);ui->lineEdit->setPlaceholderText("Please enter:");//文本框提示//csv文件读取QStringList *word=new QStringList;QStringList *trans=new QStringList;ReadCsvFile(word,trans);//搜索框下拉选项实现QCompleter *MyInfor = new QCompleter(*word);MyInfor->setMaxVisibleItems(10);//设置下拉选项可见数量ui->lineEdit->setCompleter(MyInfor);
QStringList *data=new QStringList;if(word->size()==trans->size()){for(int i=0;i<word->size();i++){QString str;str=word->at(i)+' '+trans->at(i);data->push_back(str);}}

读取csv文件操作,QFile 类是Qt中进行文件读写操作的类,使用 QFile 可以直接打开或保存文本文件。QFile::open() 函数打开文件时需要传递 QIODevice::OpenModeFlag 枚举类型的参数,决定文件以什么方式打开,QIODevice::ReadOnly为以只读方式打开文件,用于载入文件。

void Widget::ReadCsvFile(QStringList *word,QStringList *trans)
{QFile inFile(":/data/EnWords.csv");QStringList lines; if (inFile.open(QIODevice::ReadOnly)){QTextStream stream_text(&inFile);while (!stream_text.atEnd()){lines.push_back(stream_text.readLine());}for (int j = 0; j < lines.size(); j++){QString line = lines.at(j);int pos=0;for(int i=0;i<line.size();i++){if(line[i]==','){pos=i;break;}}QString str1=line.mid(0,pos);QString str2=line.mid(pos+1,line.size()-pos-1);//去除引号str1.remove(0,1);str1.remove(str1.size()-1,1);word->push_back(str1);str2.remove(0,1);str2.remove(str2.size()-1,1);trans->push_back(str2);}inFile.close();}
}

顺序表查词操作,逐个检查关键字是否满足给定的条件。若查找到某个元素的关键字满足v[i].at(j)==' ',则查找成功,返回该元素在线性表中的位置。

QString Widget::SearchTrans1(QVector<QString>v,QString str)//顺序表搜索查词
{int amount=0;for(int i=0;i<v.size();i++){int pos=0;for(int j=0;j<v[i].size();j++){if(v[i].at(j)==' '){pos=j;break;}}QString s = v[i].mid(0, pos);//分割字符串if(str==s){amount=i+1;qDebug()<<"对比次数"<<amount;return v[i];}}return QString("0");
}

使用BST树查词操作,用bst对象调用Search函数,并设置了变量amount记录对比次数。

QString Widget::SearchTrans2(BST bst,QString str)//BST搜索查词
{BSTNode *bn=new BSTNode;int amount=0;bn=bst.Search(str,bst.root,amount);if(bn==NULL)return QString("0");else{qDebug()<<"对比次数为:"<<amount;return bn->data;}
}

四、测试结果

界面显示:

下拉词汇显示:

查询结果:

五、源代码 

bst.cpp

#include "bst.h"
#include <QDebug>bool BST::Insert(QString str,BSTNode *&rootPtr)//插入结点
{if(rootPtr==NULL){rootPtr=new BSTNode(str);if(rootPtr==NULL)qDebug()<<"错误!";return true; }else if(str<rootPtr->data)Insert(str,rootPtr->left);else if(str>rootPtr->data)Insert(str,rootPtr->right);elsereturn false;
}bool BST::Build1(QVector<QString> v)//常规方法建树
{if(v.size()==0)return false;for(int i=0;i<v.size();i++)Insert(v.at(i),root);return true;
}bool BST::Build2(QVector<QString> v)//折半建树
{if (v.size() == 0)return false;int mid;mid = v.size() / 2;Insert(v[mid], root);QVector<QString> pre = v;for (int i = 0; i < v.size() - mid; i++){QVector<QString>::iterator pEnd = pre.end();pre.erase(--pEnd);//折半左侧序列}Build2(pre);QVector<QString> post = v;for (int i = 0; i < mid + 1; i++){QVector<QString>::iterator pBegin = post.begin();post.erase(pBegin);//折半右侧序列}Build2(post);
}BSTNode* BST::Search(QString str,BSTNode* rootPtr,int &amount)//搜索结点
{BSTNode* temp = new BSTNode;temp = rootPtr;while (temp != NULL){int pos=0;for(int i=0;i<temp->data.size();i++){if(temp->data.at(i)==' '){pos=i;break;}}QString s = temp->data.mid(0, pos);qDebug()<<s;amount++;if (str < s)temp = temp->left;else if (str > s)temp = temp->right;elsereturn temp;}return NULL;
}

bst.h

#ifndef BST_H
#define BST_H#include <stdlib.h>
#include <QString>
#include <QVector>struct BSTNode
{QString data;BSTNode *left,*right;//构造函数BSTNode():left(NULL),right(NULL){}BSTNode(QString str,BSTNode *l=NULL,BSTNode *r=NULL):data(str),left(l),right(r){}//析构函数~BSTNode(){}
};class BST
{
public:BSTNode *root;//构造和析构BST():root(NULL){}BST(BSTNode *r):root(r){}~BST(){}bool Insert(QString str,BSTNode *&rootPtr);//插入结点bool Build1(QVector<QString> v);//常规方法建树bool Build2(QVector<QString> v);//折半方法建树BSTNode* Search(QString str,BSTNode *rootPtr,int &amount);//搜索结点
};#endif // BST_H

main.cpp

#include "widget.h"
#include <QApplication>
#include <QTextCodec>int main(int argc, char *argv[])
{QTextCodec *codec=QTextCodec::codecForName("UTF-8");//使用UTF8使中文正常显示QTextCodec::setCodecForLocale(codec);QApplication a(argc, argv);Widget w;w.setWindowTitle("Translate");w.show();return a.exec();
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);setFixedSize(420,680);ui->lineEdit->setPlaceholderText("Please enter:"); //csv文件读取QStringList *word=new QStringList;QStringList *trans=new QStringList;ReadCsvFile(word,trans); QCompleter *MyInfor = new QCompleter(*word);MyInfor->setMaxVisibleItems(10);//设置下拉选项可见数量ui->lineEdit->setCompleter(MyInfor);QStringList *data=new QStringList;if(word->size()==trans->size()){for(int i=0;i<word->size();i++){QString str;str=word->at(i)+' '+trans->at(i);data->push_back(str);}}QVector<QString> v;for(int i=0;i<data->size();i++)v.push_back(data->at(i));BST bst;//bst.Build1(v);//常规BST建树bst.Build2(v);//折半建树connect(ui->pushButton,&QPushButton::clicked,[=](){QString desWord=ui->lineEdit->text();//BST查找方式//QString desTrans=SearchTrans2(bst,desWord);//顺序查找方式QString desTrans=SearchTrans1(v,desWord);if(desTrans=="0")ui->textEdit->setText("Not Found:(");elseui->textEdit->setText(desTrans);});
}Widget::~Widget()
{delete ui;
}void Widget::ReadCsvFile(QStringList *word,QStringList *trans)//读取csv文件
{QFile inFile(":/data/EnWords.csv");QStringList lines; if (inFile.open(QIODevice::ReadOnly)){QTextStream stream_text(&inFile);while (!stream_text.atEnd()){lines.push_back(stream_text.readLine());}for (int j = 0; j < lines.size(); j++){QString line = lines.at(j);//逐行取出//以逗号分割当前行int pos=0;//第一个逗号的位置for(int i=0;i<line.size();i++){if(line[i]==','){pos=i;break;}}QString str1=line.mid(0,pos);QString str2=line.mid(pos+1,line.size()-pos-1);//去除引号str1.remove(0,1);str1.remove(str1.size()-1,1);word->push_back(str1);str2.remove(0,1);str2.remove(str2.size()-1,1);trans->push_back(str2);}inFile.close();}
}QString Widget::SearchTrans1(QVector<QString>v,QString str)//顺序表搜索查词
{int amount=0;for(int i=0;i<v.size();i++){int pos=0;for(int j=0;j<v[i].size();j++){if(v[i].at(j)==' '){pos=j;break;}}QString s = v[i].mid(0, pos);//分割字符串if(str==s){amount=i+1;qDebug()<<"对比次数"<<amount;return v[i];}}return QString("0");
}QString Widget::SearchTrans2(BST bst,QString str)//BST搜索查词
{BSTNode *bn=new BSTNode;int amount=0;bn=bst.Search(str,bst.root,amount);if(bn==NULL)return QString("0");else{qDebug()<<"对比次数为:"<<amount;return bn->data;}
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QStringList>
#include <QString>
#include <QCompleter>
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <QVector>
#include "bst.h"namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();void ReadCsvFile(QStringList *word,QStringList *trans);//读取csv文件QString SearchTrans1(QVector<QString>v,QString str);//顺序表搜索查词QString SearchTrans2(BST bst,QString str);//BST搜索查词private:Ui::Widget *ui;
};
#endif

【数据结构】英汉翻译小词典相关推荐

  1. 【Python 实战基础】如何实现一个英汉翻译小字典

    目录 一.实战场景 二.主要知识点 三.菜鸟实战 1.创建 python 文件 2.文件目录 3.运行结果 一.实战场景 英汉字典:输入英文,返回对应中文. 二.主要知识点 文件读写 基础语法 异常处 ...

  2. 英汉计算机技术小词典,英汉计算机技术小词典

    英汉计算机技术小词典 出版时间:2001年02月 定 价:32.00 I S B N :9787313026071 所属分类: 计算机•网络 &nbsp计算机•网络  >  计算机理论  ...

  3. 计算机专业词典_好书优选:实用英汉汉英计算机词典

    购买入口: 基本信息 书名:实用英汉汉英计算机词典 价格:98.00元 作者:王能琴,谢建勋 主编 出版社:北京航空航天大学出版社 出版日期:2009-03-01 ISBN:9787811243116 ...

  4. Python控制台英汉-汉英电子词典

    2019独角兽企业重金招聘Python工程师标准>>> Python控制台英汉-汉英电子词典 By qianghaohao(CodeNutter) 用python实现了下控制台电子词 ...

  5. Python控制台英汉-汉英电子词典(代码分享)

    Python控制台英汉-汉英电子词典 By qianghaohao(CodeNutter) 用python实现了下控制台电子词典,数据来自有道,通过向有道发送http表单数据, 然后将服务器返回的js ...

  6. [翻译]《高级英汉翻译理论与实践》摘录

    前言 最近尝试了给一个小视频英语字幕做翻译,翻译结果放到了 github 上面.随后想了解更多翻译知识,就入手了一本书--叶子南教授的<高级英汉翻译理论与实践>.这虽然是本教材书,但是语言 ...

  7. c语言英汉互译编程,用C语言编辑简单英汉互译词典.doc

    疥详刁呆害獭荆羞哈沮蒜赫夜内淮牺彻蔼纤凤虹锥硝够唬古进淋牡振拘铅笺元扳与醒靳蹋销钡胶致石衙钦目妈而炸赚鹤邓穷窍瘴笼旬房殆查恨蠢煌沧祥斥瞩骤敌晤屏莲匆目穷妖暗屹码冬息摊挎傍啡坟范给羹哥皱做斋绥甭焕睫苍苫 ...

  8. 【渝粤题库】陕西师范大学200471 英汉翻译

    <英汉翻译>作业 I. Please translate the following phrases and the underlined part in each sentence. 1 ...

  9. 为VB应用程序添加英汉翻译功能

    原来写了一个利用IE浏览器通过google进行英汉翻译的代码,后来才发现在某些机器上后由于对话框阻塞而不能运行,因此,在SupermanKing的代码启发下,干脆也改用XMLHTTP进行数据提交,并完 ...

最新文章

  1. document.all与WEB标准
  2. 学习笔记CB013: TensorFlow、TensorBoard、seq2seq
  3. 台式计算机l小时耗电,电脑一天的耗电量是多少?不算不知道 一算吓一跳!
  4. linux mysql 知乎_在 Linux 上安装 MariaDB 或 MySQL | Linux 中国
  5. 使用 C# 实现 URL 安全的 Base62 转码
  6. python manage.py syncdb Unknown command: 'syncdb'问题解决方法
  7. (绝对有用)iOS获取UUID,并使用keychain存储
  8. 弹出框 背景固定 滑动
  9. 给iOS库添加Cocoapods支持
  10. Python第三方库使用 —— PIL
  11. C++基础教程之引用
  12. 基于c语言的成绩管理系统,基于C语言实现学生成绩管理系统.docx
  13. uni.request在接口状态码403等还是走success
  14. 思维模型 后天天赋(盖洛普天赋分析)
  15. 光伏发电matlab模块,光伏发电的matlab仿真.docx
  16. js中定义变量时单引号和双引号的区别
  17. iOS进阶 - GCD总结
  18. 并行接口8255芯片
  19. table表格表头单元格添加斜线
  20. 纯js实现俄罗斯方块详解与源码

热门文章

  1. 在线支付接口开发总结
  2. MySQL中去前导0的方法
  3. 单文件组件.vue 文件
  4. 塔木德分财产 思路+图片易懂 2022
  5. 终于消停了,远离百家号!
  6. ORACLE SQL and SQL*PLUS 学习
  7. Python——sklearn库的安装
  8. 微信小程序设置背景图片在手机端不显示的问题
  9. OpenGL学习之着色器详解
  10. 社区故事|SmartX 用户社区技术发烧友独家专访