问题描述

你旅游到了一个国外的城市。那里的人们说的外国语言你不能理解。不过幸运的是,你有一本词典可以帮助你。
输入:
首先输入一个词典,词典中包含不超过100000个词条,每个词条占据一行。
每一个词条包括一个英文单词和一个外语单词,两个单词之间用一个空格隔开。
而且在词典中不会有某个外语单词出现超过两次。词典之后是一个空行,然后给出一个由外语单词组成的文档,
文档不超过100000行,而且每行只包括一个外语单词。输入中出现单词只包括小写字母,而且长度不会超过12。
输出:
在输出中,你需要把输入文档翻译成英文,每行输出一个英文单词。
如果某个外语单词不在词典中,就把这个单词翻译成“eh”。

解题思路:
1.首先要做一个词典结构体数组,里面包含了英文和方言
2.然后就是输入赋值给数组:这里我采用了从外部文件读取的方式,并将词条存入我创建的词典结构体数组中
3.要对词典的方言进行一个排序,因为我们是按照方言找对应词条数组下表,然后得到它对应的英文,我采用了快速排序的方法
4.然后将输入的单词与词条的方言进行比对,并返回词典结构体数组的下标,采用二分法,每次都取中间的下标对应的值进行比较大小
这样每次都少比较一半的单词
5.打印结果

存在的问题:
每一次只能查一个单词
可改进思路:
1.设置一个char[][],一次读很多个,然后依次解析并输出翻译结果。
2.可以把待翻译的英文也存在一个txt中,然后将翻译结果写入一个新建的txt中,这样就不需要自己敲单词了。

代码及说明

#include "pch.h"
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<string>
#include <fstream> 
using namespace std;
const int maxn = 100000;//最大单词量
int wordcount = 0;//词典node数组的下标值
struct node //节点的结构体
{
	char english[12];//英语
	char foreign[12];//方言
};
node dictionary[maxn];//单词书

//利用快速排序算法,将词典按照方言的字母从a到z排序
void QuickSort(node array[], int start, int last)//array[]是待排序的数组,start是数组的起始下标,last是终止下标
{
	int i = start;
	int j = last;
	node temp = array[i];
	if (i < j)
	{
		while (i < j)
		{
			//strcmp的含义是将字符数组从前到后挨个进行比较,如果前面小于后面,就返回<0,如果相等就返回0
			while (i < j &&  strcmp(array[i].foreign, array[j].foreign) < 0)
				j--;
			
			if (i < j){
				array[i] = array[j];
				i++;
			}
			while (i < j && strcmp(array[i].foreign, array[j].foreign)>0)
				i++;
			
			if (i < j)
            {
				array[j] = array[i];
				j--;
			}
		}
		//把基准数放到i位置
		array[i] = temp;
		//递归方法
		QuickSort(array, start, i - 1);
		QuickSort(array, i + 1, last);
	}
}

//二分法查找
int bsearch(char *s, int n) 
{
	int mid, start, end;
	start = 0; end = n - 1;
	int flag = 0;
	while (start <= end)
	{
		mid = (start + end) / 2;//从中间位置开始找
		flag = strcmp(s, dictionary[mid].foreign);//比较输入的单词和中间位置下标的方言是否一致
		if (flag == 0)//如果为0证明恰好就是它,把下标返回就可以了
			return mid;
		if (flag < 0)//小于0就在左边部分找,否则就在右半部分找
		{
			end = mid - 1;
		}
		else
		{
			start = mid + 1;
		}
	}
	return -1;
}

//读取词典的函数
//将词典以单词的形式读取并存入到dictionary数组中
void readDectionary() {
	const char filename[] = "D:\\dictionary.txt";
	ifstream i_file;
	string out_text;//输出的单词
	//读 
	i_file.open(filename);
	if (i_file.is_open())
	{
		//k是为了判断读取的单词是基数还是偶数
		//目的是为了判断放入英语还是方言的char[]中,在txt文档中,基数为英语,偶数为方言(格式是先写英语然后再空格写方言)
		int k = 0;
		while (i_file >> out_text) {
			k++;
			//这里定义了一个字符数组,将获取的单词string转为char[]类型
			char dst[12];
			for (int i = 0; i<=out_text.length(); i++) {
					dst[i] = out_text[i];
					
			}
			//余数为1则为基数
			if(k%2==1){
				memcpy(dictionary[wordcount].english, dst, sizeof(dst));
				cout << dictionary[wordcount].english << endl;
			}
			else {
				memcpy(dictionary[wordcount].foreign, dst, sizeof(dst));
				cout << dictionary[wordcount].foreign << endl;
				wordcount++;//dictionary恰好存入一组英语和方言,下标值加1
			}			
		}		
	}
	else
		cout << "打开文件:" << filename << "时出错!";

	i_file.close();
}
int main() {
	//读取词典,按照单词读取:
	readDectionary();
	//快速排序
	QuickSort(dictionary, 0, wordcount);
	//输入待翻译的单词
	cout << "请输入单词" << "\n";
	char word[12];
	cin >> word;
	//在词典中找方言,并将词典下标值返回给P
	int p;
	p = bsearch(word, wordcount);
	//判断词典中是否有对应的翻译
	if (p == -1) {
		cout << "ch" << "\n";
	}
	else {
		cout << dictionary[p].english;
	}
		

}

运行结果截图:
算法3:Babelfish(分治法+快速排序)_算法
算法3:Babelfish(分治法+快速排序)_算法_02