【求解】电脑文件索引的建立【诶,我又来发帖了,虽然总共就发了一帖

AOYk 2015-04-25 06:59:43
总需求:实现电脑(windows系统下的)本地文件搜索功能(从很多文件中


目前已经知道并且做到了
完全扫描磁盘的所有文件
并且能将扫描的结果逐条输出(如输出到txt)

其实如果暴力些,能做到上面的基本上就能做到搜索了
[另外不要看到搜索的都是Eclipse就意味本人用的是Java....需要C++....

不过

为了能够加快文件搜索的速率,
需要建树什么的....
【个人认为,
如果能在扫描的结果上建树(或者其他类似的结构,
就不用每次在用户进行搜索的时候重新扫描磁盘,
直接从以前扫描的记录中搜索就会快些,
而且考虑到树的各种性质,
又能大概有一个比较让人接受的算法
】


那么问题来了,
树的逻辑结构应当是怎么样的?
有一大堆文件、文件夹的名字和路径
应该基于什么样的原则或者规则建树(或者其他东西
才能切实有效的加快搜索的速度?
现在个人完全一点头绪都没有,
因为之前学到的树都是有一个确切的数值大小可以进行比较的,
可是如果是文件名这些就完全不知道怎么搞了

当然,如果您能介绍一些其他的文件搜索程序的实现思路
【比如类似everything使用USN日志之类的】
完!全!欢!迎,,,,
不过出于【数据结构课程】的要求
需要有一定的数据结构和算法,,,
当然您们就不用考虑这些.........
请告诉我思路和想法就好...
当然具体的越详细越好。。。。。。

拜谢各位大侠、码神
...全文
635 14 打赏 收藏 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
AOYk 2015-05-01
  • 打赏
  • 举报
回复
引用 13 楼 zhao4zhong1 的回复:
楼主不放试试使用STL regex:
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main() {
...
感谢指教...
赵4老师 2015-04-29
  • 打赏
  • 举报
回复
楼主不放试试使用STL regex:
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main() {
    string str("This expression could match from A and beyond. [ expression  express ]");
    string rs = "exp\\w*";  // 正则字符串,exp开始的单词
    cout << str << endl;

    regex expression(rs); // 字符串传递给构造函数,建立正则表达式

// regex_match 判断一个正则表达式(参数 e)是否匹配整个字符序列 str. 它主要用于验证文本。
// 注意,这个正则表达式必须匹配被分析串的全部,否则函数返回 false.
// 如果整个序列被成功匹配,regex_match 返回 True.
    bool ret = regex_match(str, expression);
    if (ret)
        cout << "可以匹配整个文本" << endl;
    else
        cout << "不能匹配整个文本" << endl;

// regex_search 类似于 regex_match, 但它不要求整个字符序列完全匹配。
// 你可以用 regex_search 来查找输入中的一个子序列,该子序列匹配正则表达式 e.
    ret = regex_search(str, expression);
    if (ret)
        cout << "能够搜索到 " << rs << endl;
    else
        cout << "不能搜索" << endl;

// regex_replace 在整个字符序列中查找正则表达式e的所有匹配。
// 这个算法每次成功匹配后,就根据参数fmt对匹配字符串进行格式化。
// 缺省情况下,不匹配的文本不会被修改,即文本会被输出但没有改变。

    str = regex_replace(str, expression, string("表达式"));
// VC2010或者TR1注意:这里第三个参数要用string()转换
// http://www.johndcook.com/cpp_regex.html
// started with C++ TR1 regular expressions
    cout << str << endl;
    return 0;
}
//This expression could match from A and beyond. [ expression  express ]
//不能匹配整个文本
//能够搜索到 exp\w*
//This 表达式 could match from A and beyond. [ 表达式  表达式 ]
AOYk 2015-04-29
  • 打赏
  • 举报
回复
引用 8 楼 worldy 的回复:
[quote=引用 4 楼 a0178298 的回复:] [quote=引用 1 楼 worldy 的回复:] 简单而直接的方法就...索引,你回答是就是了
能说下索引大概是什么样子的么。。。...索引的逻辑结构什么的完全不知道.... [/quote] 一个文件名字段一个位置字段 组成数组 按文件名排序 这样你只要找到文件名就找到位置了[/quote] 之前是打算用这种方式的,, 不过对于文件夹和其下的文件的关系不太好表示,,, 而且这样排的话需要额外写一个字典序排序.............. 之前打算用字符编码直接转成数值, 类似于Hash一样一步到位的查找索引, 不过发现会出现不同名文件数值重复的情况(加法交换律啦 乘法交换律啦 结合律等情况存在时.. 所以就放弃咧
AOYk 2015-04-29
  • 打赏
  • 举报
回复
引用 7 楼 cjqpker 的回复:
[quote=引用 6 楼 a0178298 的回复:] [quote=引用 2 楼 cjqpker 的回复:] 重点是....你要监控文件变动,去更改你的索引 .....就算你存成数组,查找也花不了多少时间。同一楼说,排序存放,二分查找即可
整个磁盘的文件存成数组会装不下吧... 有好多文件啊啊啊... 每个文件都用数据成员记录这样会爆炸的吧.... ...... [/quote] 只记录文件名,怎么会爆炸呢,假设一个文件名 200个字节,一万个文件名加起来不过2MB左右。 索引结构就把文件名存在平衡二叉树里就好了。其实如果你查找的关键字可能是文件名的任何位置,就根本不用树结构,就根据目录结构存储成类似目录的链表数据结构就好了。[/quote] 目前打算用倒排表试一下...感谢
AOYk 2015-04-29
  • 打赏
  • 举报
回复
引用 9 楼 zhao4zhong1 的回复:
[quote=引用 5 楼 a0178298 的回复:] [quote=引用 3 楼 zhao4zhong1 的回复:] c:\>findstr /? 在文件中寻找字符串。 FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:file] [/C:string] [/G:file] [/D:dir list] [/A:color attributes] [/OFF[LINE]] strings [[drive:][path]filename[ ...]]
您误解我意思了,,,并不是在cmd里查找文件....是自己写一个查找文件的程序。。。。[/quote] 你误解我意思了,我是让你使用system("findstr ...>findstr.txt");//然后读文件findstr.txt的内容的方法查找你的索引文件。 参考下面: 请牢记:源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要,重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。 意思是... .... 所以 与其费劲去重构代码让其看上去更简洁、更合理 不如费劲学习grep、sed、awk、……这类全文搜索和批处理编辑的工具。 结构越复杂,越难修改,越难除错。... [/quote] ,,,呃, 如果只是单纯我自己开发的话我确实会毫不犹豫用各种现成的比较好的东西, 而不是自己去实现一些已有的。 不过现在问题是这是我课程作业, 老师特别声明不能用这些东西 (其实是为了锻炼设计算法和数据结构的能力诶.... 所以.... 不过还是很感谢您的指教...
赵4老师 2015-04-27
  • 打赏
  • 举报
回复
引用 5 楼 a0178298 的回复:
[quote=引用 3 楼 zhao4zhong1 的回复:] c:\>findstr /? 在文件中寻找字符串。 FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:file] [/C:string] [/G:file] [/D:dir list] [/A:color attributes] [/OFF[LINE]] strings [[drive:][path]filename[ ...]]
您误解我意思了,,,并不是在cmd里查找文件....是自己写一个查找文件的程序。。。。[/quote] 你误解我意思了,我是让你使用system("findstr ...>findstr.txt");//然后读文件findstr.txt的内容的方法查找你的索引文件。 参考下面: 请牢记:源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要,重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。 意思是你程序结构看上去再合理,再简洁,也不一定比看上去一团乱麻的程序结构在运行或修改时更不易出错,更方便修改,出错了更容易找到哪里出错和具体出错的原因,更容易改正错误。 试对比 图书馆(对图书的分类够结构化了吧) 和 搜索引擎(可看作是扁平化任何结构数据,仅支持全文检索) 哪个处理信息更方便、更高效。 所以 与其费劲去重构代码让其看上去更简洁、更合理 不如费劲学习grep、sed、awk、……这类全文搜索和批处理编辑的工具。 结构越复杂,越难修改,越难除错。 有时(甚至大多数时候),看上去越合理、越简洁的代码,运行起来性能越差,出错时查找原因越难,找到出错原因后改正越费劲。 程序员要做的不是尽力避免错误,而是聚焦在快速发现并改正错误。真正以快速方式轻易解决错误,“快速的失败”远胜过“预防错误”。Fred George
赵4老师 2015-04-26
  • 打赏
  • 举报
回复
c:\>findstr /? 在文件中寻找字符串。 FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:file] [/C:string] [/G:file] [/D:dir list] [/A:color attributes] [/OFF[LINE]] strings [[drive:][path]filename[ ...]] /B 在一行的开始配对模式。 /E 在一行的结尾配对模式。 /L 按字使用搜索字符串。 /R 将搜索字符串作为一般表达式使用。 /S 在当前目录和所有子目录中搜索匹配文件。 /I 指定搜索不分大小写。 /X 打印完全匹配的行。 /V 只打印不包含匹配的行。 /N 在匹配的每行前打印行数。 /M 如果文件含有匹配项,只打印其文件名。 /O 在每个匹配行前打印字符偏移量。 /P 忽略有不可打印字符的文件。 /OFF[LINE] 不跳过带有脱机属性集的文件。 /A:attr 指定有十六进位数字的颜色属性。请见 "color /?" /F:file 从指定文件读文件列表 (/ 代表控制台)。 /C:string 使用指定字符串作为文字搜索字符串。 /G:file 从指定的文件获得搜索字符串。 (/ 代表控制台)。 /D:dir 查找以分号为分隔符的目录列表 strings 要查找的文字。 [drive:][path]filename 指定要查找的文件。 除非参数有 /C 前缀,请使用空格隔开搜索字符串。 例如: 'FINDSTR "hello there" x.y' 在文件 x.y 中寻找 "hello" 或 "there"。'FINDSTR /C:"hello there" x.y' 文件 x.y 寻找 "hello there"。 一般表达式的快速参考: . 通配符: 任何字符 * 重复: 以前字符或类出现零或零以上次数 ^ 行位置: 行的开始 $ 行位置: 行的终点 [class] 字符类: 任何在字符集中的字符 [^class] 补字符类: 任何不在字符集中的字符 [x-y] 范围: 在指定范围内的任何字符 \x Escape: 元字符 x 的文字用法 \<xyz 字位置: 字的开始 xyz\> 字位置: 字的结束 有关 FINDSTR 常见表达法的详细情况,请见联机命令参考。
假正经的班长 2015-04-26
  • 打赏
  • 举报
回复
重点是建立索引之后,文件发生变更,你要监控文件变动,去更改你的索引 否则如果仅仅是一次性的工作,就算你存成数组,查找也花不了多少时间。同一楼说,排序存放,二分查找即可
worldy 2015-04-26
  • 打赏
  • 举报
回复
引用 4 楼 a0178298 的回复:
[quote=引用 1 楼 worldy 的回复:] 简单而直接的方法就是为文件建立索引,然后使用二分搜索即可,事实上,你也不用考虑这些,在win7系统上,当你搜搜文件得时候,系统会问你是否建立索引,你回答是就是了
能说下索引大概是什么样子的么。。。 我不知道怎么建索引啊啊啊...... 索引的逻辑结构什么的完全不知道.... [/quote] 一个文件名字段一个位置字段 组成数组 按文件名排序 这样你只要找到文件名就找到位置了
假正经的班长 2015-04-26
  • 打赏
  • 举报
回复
引用 6 楼 a0178298 的回复:
[quote=引用 2 楼 cjqpker 的回复:] 重点是建立索引之后,文件发生变更,你要监控文件变动,去更改你的索引 否则如果仅仅是一次性的工作,就算你存成数组,查找也花不了多少时间。同一楼说,排序存放,二分查找即可
整个磁盘的文件存成数组会装不下吧... 有好多文件啊啊啊... 每个文件都用数据成员记录这样会爆炸的吧.... 而且说实话不知如何监控文件变动/// 目前想法是每重新启动一次程序就重新建立一次索引...也提供立即重新扫描的按钮之类的什么... [/quote] 只记录文件名,怎么会爆炸呢,假设一个文件名 200个字节,一万个文件名加起来不过2MB左右。 索引结构就把文件名存在平衡二叉树里就好了。其实如果你查找的关键字可能是文件名的任何位置,就根本不用树结构,就根据目录结构存储成类似目录的链表数据结构就好了。
AOYk 2015-04-26
  • 打赏
  • 举报
回复
引用 2 楼 cjqpker 的回复:
重点是建立索引之后,文件发生变更,你要监控文件变动,去更改你的索引 否则如果仅仅是一次性的工作,就算你存成数组,查找也花不了多少时间。同一楼说,排序存放,二分查找即可
整个磁盘的文件存成数组会装不下吧... 有好多文件啊啊啊... 每个文件都用数据成员记录这样会爆炸的吧.... 而且说实话不知如何监控文件变动/// 目前想法是每重新启动一次程序就重新建立一次索引...也提供立即重新扫描的按钮之类的什么...
AOYk 2015-04-26
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
c:\>findstr /? 在文件中寻找字符串。 FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:file] [/C:string] [/G:file] [/D:dir list] [/A:color attributes] [/OFF[LINE]] strings [[drive:][path]filename[ ...]]
您误解我意思了,,,并不是在cmd里查找文件....是自己写一个查找文件的程序。。。。
AOYk 2015-04-26
  • 打赏
  • 举报
回复
引用 1 楼 worldy 的回复:
简单而直接的方法就是为文件建立索引,然后使用二分搜索即可,事实上,你也不用考虑这些,在win7系统上,当你搜搜文件得时候,系统会问你是否建立索引,你回答是就是了
能说下索引大概是什么样子的么。。。 我不知道怎么建索引啊啊啊...... 索引的逻辑结构什么的完全不知道....
worldy 2015-04-25
  • 打赏
  • 举报
回复
简单而直接的方法就是为文件建立索引,然后使用二分搜索即可,事实上,你也不用考虑这些,在win7系统上,当你搜搜文件得时候,系统会问你是否建立索引,你回答是就是了

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧