词典查找算法

        1.算法介绍

        这个程序的功能是:随机生成一个词典,10w左右的词,每个词是10~30的英文字母串,实现词典查找算法,即给定任意一个字符串,去看在词典中是否存在

整体的思路是:

        (1)字符串生成函数。该函数能够生成长度在10~30之间的字符串,字符串的长度是随机的,字符也都是随机的。

        (2)生成10w个字符串,将字符串写入文件。

        (3)读取刚才生成的词典文件,将其中的字符串读出,每个字符串作为一个词条。词典用vector来存储。

        (4)对词典中的词条进行排序,按照字母表的顺序进行存储。排序使用快速排序算法,其中快速排序的枢轴选择上选用首、尾、中间三个数的之间置,并且在递归到规模比较小的时候使用插入排序,以减少递归过程不断创建函数的开销。

        (5)在排好序的词典中查找目标字符串。字符串查找采用二分查找法。

        (6)将排序和查找过程用C++标准库中的sort()和find()函数实现,观察我的函数和标准库中的函数的性能。

        2.时间复杂度分析

        快速排序的时间复杂度为nlogn,二分查找的时间复杂度为logn。通过与标准库中的函数进行对比,发现自己写的函数同标准库中的函数性能上有差距。

               


        3.源代码

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>	//函数srand()
#include <ctime>	//函数time()
#include <vector>
#include <sys/time.h>
#include <algorithm>

using namespace std;

const long LEN = 100000;	//词典的规模
const int MAX = 30;		//词条的最大长度
const int MIN = 10;		//词条的最小长度
int limit_value = 25;		//进行插入排序的阈值

//生成随机字符串
string rand_string(int min, int max){
	char a[MAX+1];
	int len = rand()%(max - min) + min;
	for(int i = 0; i < len; i++){
		a[i] = rand()%26 + 'a';
	}
	a[len] = '\0';
	string str(a);
	return str;
}

//将字符串写入文件,构建词典
void write_dict(){
	ofstream fout;
	fout.open("dict.txt");
	srand((unsigned)time(NULL));
	for(int i = 0; i < LEN; i++){
		string str = rand_string(10, 30); 
		fout << str << '\n';
		fout << flush;
	}
	fout.close();
}

//从文件中读取词典信息
vector<string> read_dict(){
	ifstream fin;
	fin.open("dict.txt");
	string textline;
	vector<string> dict;
	while(getline(fin, textline, '\n')){
		dict.push_back(textline);
	}
	return dict;
}


//比较函数,用于比较两个字符串的相对大小
int compare(string &x, string &y){
	int xlen = x.size();
	int ylen = y.size();
	int i = 0;
	while(i < xlen && i < ylen){
		if(x[i] == y[i]){
			i++;
		}else if(x[i] > y[i]){
			return 1;
		}else{
			return -1;
		}
	}
	if(xlen == ylen){
		return 0;
	}
	if(i == xlen){
		return -1;
	}
	if(i == ylen){
		return 1;
	}
}

//对原始词典中的词进行排序,建立新的词典,新词典顺序排列
//插入排序
void insert_sort(vector<string> &dict, int low, int high){
	for(int i = low + 1; i <= high; i++){
		string tmp = dict[i];
		for(int j = i - 1; j >= low; j--){
			if(compare(tmp, dict[j]) < 0){
				dict[j+1] = dict[j];
			}else{
				dict[j+1] = tmp;
				break;
			}
		}
	}
}

//枢轴元素的选取,三者取中
void select_PivotMid(vector<string> &dict, int low, int high){
	int mid = low + ((high - low) >> 1);
	if(compare(dict[mid], dict[high])){
		swap(dict[mid], dict[high]);
	}
	if(compare(dict[low], dict[high])){
		swap(dict[low], dict[high]);
	}
	if(compare(dict[mid], dict[low])){
		swap(dict[mid], dict[high]);
	}
}
//快速排序,其中枢轴是三者取中,到一定程度用插入排序
void quick_sort(vector<string> &dict, int low, int high){
	if(low < high){
		if(high - low < limit_value){
			insert_sort(dict, low, high);
		}else{
			select_PivotMid(dict, low, high);
			string pivot = dict[low];
			int i = low, j = high;
			while(i < j){
				while(i < j && compare(dict[j], pivot) > 0){
					j--;
				}
				if(i < j){
					dict[i] = dict[j];
					i++;
				}
				while(i < j && compare(dict[i], pivot) < 0){
					i++;
				}
				if(i < j){
					dict[j] = dict[i];
					j--;
				}
			}
			dict[i] = pivot;
			quick_sort(dict, low, i - 1);
			quick_sort(dict, i + 1, high);
		}
	}
}
//验证排序是否正确
int verify(vector<string> &dict){
	for(int i = 0; i < dict.size() - 1; i++){
		if(dict[i] > dict[i+1]){
			cout << i << endl;
			return -1;
		}
	}
	return 0;
}

//二分搜索,在字典中搜索目标字符串是否存在
int binary_search(string &str, vector<string> dict){
	int low = 0;
	int high = dict.size();
	int pos = 0;
	while(low <= high){
		int mid = (low + high)/2;
		int flag = compare(dict[mid], str);
		if(flag == 0){
			return mid;
		}else if(flag > 0){
			high = mid - 1;
		}else{
			low = mid + 1;
		}
	}
	return -1;
}

long getCurrentTime(){
	struct timeval tv;
	gettimeofday(&tv, NULL);
	return tv.tv_sec*1000 + tv.tv_usec/1000;
}


int main(){
	//string a = rand_string(MIN,MAX);
	string a = "siubetamwm";

	//1.1读取数据
	vector<string> dict = read_dict();

	cout << "我的算法:" << endl;
	//1.2排序
	long time_1 = getCurrentTime();
	quick_sort(dict, 0, dict.size()-1);
	long time_2 = getCurrentTime();
	int isTrue = verify(dict);
	cout << "  排序结果:" << ((isTrue >= 0) ? "Yes" : "No") << endl;
	
	//1.3搜索
	long time_3 = getCurrentTime();
	int isFind = binary_search(a, dict);
	cout << "  搜索结果:" << ((isFind >= 0) ? "Yes" : "NO") << endl;
	long time_4 = getCurrentTime();
	
	cout << "模板算法:" << endl;
	//2.1读取数据
	vector<string> dict_2 = read_dict();

	//2.2排序
	long time_5 = getCurrentTime();
	sort(dict_2.begin(), dict_2.end());
	long time_6 = getCurrentTime();
	int isTrue_2 = verify(dict_2);
	cout << "  排序结果:" << ((isTrue_2 >= 0) ? "Yes" : "No") << endl;
	
	//2.3搜索
	long time_7 = getCurrentTime();
	vector<string>::iterator s = find(dict_2.begin(), dict_2.end(), a);
	int isFind_2 = -2;
	if(s != dict_2.end()){
		isFind_2 = 0;
	}else{
		isFind_2 = -1;
	}
	cout << "  搜索结果:" << ((isFind_2 >=0) ? "Yes" : "No") << endl;
	long time_8 = getCurrentTime();
	
	cout << endl;
	
	cout << "我的算法:" << endl;
	cout << "  排序时间:" << time_2 - time_1 << endl;
	cout << "  搜索时间: " << time_4 - time_3 << endl;
	
	cout << "模板算法:" << endl;
	cout << "  排序时间:" << time_6 - time_5 << endl;
	cout << "  搜索时间:" << time_8 - time_7 << endl;
}



  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值