从多个文件中搜索指定单词功能实现

本文介绍了一款用于在Windows下搜索指定单词的小程序,该程序可指定文件夹和过滤文件扩展名,能快速定位到单词所在的文件和行号。程序采用C++重写,具备Unicode支持,首次初始化时间较长,但后续查询效率高。目前仅支持连续字母的全字匹配,未来计划增加界面和非单词字符串搜索功能。
摘要由CSDN通过智能技术生成

前两天在看linux内核代码,因为还没有很熟悉,有一些函数不知道在哪个文件里,手动找很麻烦,于是在windows下写了个文件搜索单词功能的小程序。只是实现了连续字母的搜索,也花了我两个小时写程序,后面第二天又测试调度了两个小时,今天第三天又用C++重写了这个功能;算是可以使用,放出来分享一下,如果有bug,请帮忙报告一下。

1. 说明一下类CFindWord的功能:先使用Init函数附带folder参数指定目标文件夹,使用filter参数指定需要过滤的文件扩展名;这个函数把文件下所有符合过滤条件的文件中的所有单词统计位置,算是一个初始化工作;然后使用Find函数查找对应的单词在哪个文件哪一行出现过;如果需要打印则调用PrintResult;我在后面贴了一个使用例子。

2. 说明一下功能特点:可以使用Unicode或多字节编译运行;第一次初始化需要的时间比较长一点,我对linux0.11的代码4m左右初始化需要1秒左右,如果太多文件,可能需要比较长的时间。第一次初始化会解析好过滤文件名,搜索每个文件,建立文件字典;搜索文件的每行每个单词,建立单词字典;并把每个单词对应的文件ID及行号,行的内容记录;形成一个可以快速查询的综合字典,因为使用了字符串hash,所以搜索效率可以到达O(1);但没有完全测试hash碰撞情况,不排除因碰撞产生搜索结果不正确的情况。

3. 说明一下功能限制:在FindWordInLine函数中可以看出,我只实现了对字符组成的单词全字匹配,如果想加其他功能,可以在FindWordInLine这个函数里面改;比如做一些正则的匹配等。我目前对单词目标比较明确,目前没有实现正则。

4. 后期可能做的就是,加一个小界面,在windows下可以使用快捷键快速调出窗口,指定文件夹,输入单词,快速列出结果。另外,也应该实现非单词形式的字符串的搜索功能。

#pragma once

#include <vector>
#include <stack>
#include <string>
#include <list>
#include <map>

// 为了支持宽字节或多字节流做的宏
#ifdef _UNICODE
#define tstring		wstring
#define tifstream	wifstream
#define tcout		wcout
#else 
#define tstring		string
#define tifstream	ifstream
#define tcout		cout
#endif

typedef struct 
{
	DWORD fileid;
	DWORD linenumber;
	std::tstring linecontent;
}findresult;

class CFindWord
{
public:
	CFindWord(){};
	~CFindWord(){};
	// 使用此函数指定目标文件夹和过滤文件的扩展名初化文件表和词表数据
	bool Init(const std::tstring &folder,const std::tstring &filter);
	// 从已初始化好的数据中搜索对应单词结果
	DWORD Find(const std::tstring &word,std::list<findresult> &listfindresult);
	// 供测试打印用,与程序逻辑无关
	void PrintResult(std::list<findresult> &listfindresult);

private:
	// 利用hash值来快速比较字符串值
	DWORD CalcStringToHash(const TCHAR * key,DWORD len);
	// 检测文件是否是过滤的扩展名
	bool IsFilteFile(std::tstring &fullpath);
	// 取得文件列表
	DWORD GetFileList(LPCTSTR in_directory,WIN32_FIND_DATA * out_path_list, DWORD in_max_path_list_count);
	// 递归取得文件夹内所有文件
	DWORD RecurseGetFile(std::stack<std::tstring> &stack_path,std::list<std::tstring> &list_file);

	DWORD FindInFolder(const std::tstring &folder);

	
可以使用Java的File、Scanner和Map来实现统计一个文本文件单词的个数。具体实现步骤如下: 1. 创建一个File对象,指定文本文件的路径; 2. 创建一个Scanner对象,读取文本文件的内容; 3. 使用正则表达式将文本文件单词分离出来; 4. 使用Map统计每个单词的出现次数; 5. 遍历Map,输出每个单词及其出现次数。 示例代码如下: ```java import java.io.File; import java.io.FileNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class WordCount { public static void main(String[] args) { File file = new File("test.txt"); Map<String, Integer> wordCount = new HashMap<>(); try { Scanner scanner = new Scanner(file); while (scanner.hasNextLine()) { String line = scanner.nextLine(); String[] words = line.split("\\W+"); // 使用正则表达式分离单词 for (String word : words) { if (!word.isEmpty()) { // 忽略空单词 wordCount.put(word, wordCount.getOrDefault(word, 0) + 1); // 统计单词出现次数 } } } scanner.close(); for (Map.Entry<String, Integer> entry : wordCount.entrySet()) { // 遍历Map输出结果 System.out.println(entry.getKey() + ": " + entry.getValue()); } } catch (FileNotFoundException e) { e.printStackTrace(); } } } ``` 其,使用正则表达式`"\\W+"`来分离单词,`\W`表示非单词字符,`+`表示匹配一次或多次。`wordCount.getOrDefault(word, 0)`表示获取Mapkey为word的值,如果不存在则返回默认值0。`wordCount.put(word, wordCount.getOrDefault(word, 0) + 1)`表示将单词word的出现次数加1并存入Map
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值