数据结构大作业-DBLP科学文献管理系统(二)作者排序、热点分析功能,模糊搜索(桶排序,字典树)

        排序计算将在建库中执行完成,并将结果输出到文件。前端不需要做额外计算。

作者统计功能

        调用作者统计函数后,程序将一个一个将作者名读入,同时维护一个字典树,在每个树的结点记录一个权值,统计该位置对应的作者名出现了多少遍。最后再遍历字典树,获得所有作者的具体出现次数,并由于作者出现频率远小于作者总数量,因此使用桶排序可以获得最好的排序效率,最终在O(n)的时间内完成排序,占用的空间也为O(n)。排序后按顺序输出到文件中。

        其中,字典树(单词查找树)是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。

class node
	{
	public:
		static const node* Not_found;
		char str;
		DWORD weight;
		vector<node*> child;
		node(char Strings = '\0', DWORD weights = 0) {
			str = Strings;
			weight = weights;
			child.clear();
		}
		node* add_child(char String, DWORD weights = 0) {
			node* ans = new node(String, weights);
			child.push_back(ans);
			return ans;
		}
		node* find_child(char String) {
			for (vector<node*>::iterator now = child.begin(); now != child.end(); now++) {
				if ((*now)->str == String)
					return *now;
			}
			return NULL;
		}
	};
	const node* node::Not_found = NULL;

	class authors
	{
	private:
	public:
		string name;
		DWORD weight;
		authors(const string& names, const DWORD& weights) {
			name = names;
			weight = weights;
		}
		DWORD operator++() {
			return ++weight;
		}
		bool operator < (const authors& tar) {
			return this->weight < tar.weight;
		}
		bool operator > (const authors& tar) {
			return this->weight > tar.weight;
		}
		bool operator >= (const authors& tar) {
			return this->weight >= tar.weight;
		}
		bool operator <= (const authors& tar) {
			return this->weight <= tar.weight;
		}
		authors& operator =(const authors& tar) {
			name = tar.name;
			weight = tar.weight;
			return *this;
		}
	};

热点分析功能

        与作者统计函数类似,调用热点分析函数后,程序将分别将所有题目按单词读入,同时维护一个字典树,在每个树的结点记录一个权值,统计该位置对应的单词出现的频率。最后再遍历字典树,获得所有单词的具体出现次数,由于单词出现频率有大量相同,因此也使用桶排序以获得较好的排序效率,最终在O(n+m)的时间内完成排序,占用的空间也为O(n+m)。排序后按顺序输出到文件中。经过测试,桶排序的速度仍然高于其他排序方式(测试了快速排序、鸡尾酒排序、堆排序、归并排序、希尔排序,由于数据特点和规模,导致除桶排序外的所有排序方式时间均不可接受)速度。

         (这里实际刷掉了一些常用词,如is an are等)

 

部分匹配搜索功能(模糊搜索)

        为了实现快速搜索,在执行模糊搜索前,需要在内存中建立一个字典树(这里需要内存约700m,并有对应的释放数据)

int fuzzy_search(char* _saveUrl, DWORD thread_num, char* tar)
	{
		if (!is_initial) {
			cout << "未初始化" << endl;
			return false;
		}
		if (thread_num > 256)thread_num = 256;
		max_thread_num = thread_num;
		kill_me = false;
		DWORD numb = bags.size() / thread_num;
		fuzzy_target = tar;
		for (int i = 0; i < max_thread_num; i++) {
			answers[i].clear();
			finished_flag[i] = false;
			change_fuzzy_string[i] = true;
		}
		for (int i = 0; i < thread_num - 1; i++) {
			thread* tmp = new thread(calculate_thread, _saveUrl, numb * i, numb * (i + 1), i);
			tmp->detach();
		}
		thread* tmp = new thread(calculate_thread, _saveUrl, numb * (thread_num - 1), bags.size() - 1, thread_num - 1);
		tmp->detach();
		while (!check_finish()) { Sleep(100); }
		if (kill_me)return false;
		kill_me = true;
		string paths = "mkdir " + (string)_saveUrl + "database\\searchlog  2>nul";
		char* pathss = new char[paths.length() + 1];
		for (int i = 0; i < paths.length(); i++) {
			pathss[i] = paths[i];
		}
		pathss[paths.length()] = '\0';
		system(pathss);
		fstream outfile((string)_saveUrl + (string)"database\\searchlog\\" + Hash4(fuzzy_target) + ".db", ios::out);
		int tot = 0;
		for (int i = 0; i < thread_num; i++) {
			for (int j = 0; j < answers[i].size(); j++) {
				outfile << answers[i][j] << endl;
				tot++;
			}
			answers[i].clear();
		}
		outfile.close();
		return tot;
	}

        模糊搜索提供两种类型,一种是单词全字匹配,一种是完全模糊匹配。其区别在于,完全模糊会将一个单词的部分作为匹配内容,而全字匹配则不会。两种模式所采用的搜索方式完全相同,所以在这里只阐述完全模糊匹配。如图所示:

         初始化之后,调用模糊搜索函数时,创建大量线程,同时按线程数平分任务,通过KMP子串匹配算法,将所有匹配的将结果存入每个线程独立的Vector容器中。待到所有任务完成后,由主线程计算出Hash值,并将结果储存到对应文件中。在任何情况下,程序都可以在100ms内可完成所有任务。但由于IO限制,结果需要输出到文件,若结果较少,可在1s内返回;若较多,时间可能达到5s及以上。

【资源说明】 基于关联规则挖掘DBLP学者关系python源码+实验报告(数据挖掘作业).zip 基本思路 解析 DBLP 的 xml 文件,以 attention 和 transformer 为关键词,只取 2017 年以后的文章。 把人名编码成数字。 一年一年来处理,认为有效的学者关系满足两点: 一年内发表论文数量大于 5【支持率】。 关系内任意一人记为 a,除他之外其他人记为 A,要满足 A → A+a 的【置信率】大于 0.5;注意是任意一人。 定义 人数=2 的关系为【合著者】,人数>2 的关系为【团队】。 定义学者关系的【活跃程度】:α \* 这一堆人发表文章数量 + β / 人数 \* 求和{一堆人发表文章数量 / 每个人发表文章数量}。取 α=1,β=10。注意发表数量都是一年内的。 主要结论 研究 attention transformer 的人越来越多。 貌似没人能一直研究 attention transformer 超过一年,大家的研究方向变得很快。 好多活跃的人都是重复的,比如出现 “一个固定导师+一个可变学生” “两个固定导师+一个可变学生” “AB BC AC 都活跃” 这种 pattern,三五好友 / 整个实验室一起研究 transformer。 合著者发文数量上,2018年有一个激增;团队发文数量上,2019年和2021年都有激增。 文件列表 py: `getAuthors.py`:从 DBLP 的 xml 文件,解析得到 `authors.txt`。 `encodeAuthors.py`:把 `authors.txt` 编码成 `authors_encode.txt` + `author_index.txt`。 `fpgrowth.py`:调用 `mlxtend` 的关联规则挖掘,以及学者关系分析。 txt: `authors.txt`:年份 + title + 学者名字。 `authors_encode.txt`:年份 + title + 学者编码(数字)。 `author_index.txt`:学者编码 + 学者名字 + 这个人(一年内)总共发表数量。 csv: `result_co_authors_5_0.5.csv`:合著者的分析结果,年份 + 学者名字(tuple)+ 学者一年内发文数量 + 活跃程度。 `result_teams_5_0.5.csv`:团队的分析结果,格式同上。 pdf: 课程报告。 【备注】 1.项目代码均经过功能验证ok,确保稳定可靠运行。欢迎下载使用体验! 2.主要针对各个计算机相关专业,包括计算机科学、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师、企业员工。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行次开发。在使用过程中,如有问题或建议,请及时沟通。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值