社区
C++ 语言
帖子详情
我有一个txt文本文件中有10万行记录(每行约10个汉字),如何找出重复的行将其删除掉。
iGarlic
2005-10-04 03:25:23
我有一个txt文本文件中有10万行记录(每行约10个汉字),
如何找出重复的行将其删除掉(保留一行)。
这个文本文件中每一个行是一个约10个字的记录
要求快速找出并删除重复的行。
我用的vc++里的控制台程序。
请求好的算法!谢谢。
...全文
1501
15
打赏
收藏
我有一个txt文本文件中有10万行记录(每行约10个汉字),如何找出重复的行将其删除掉。
我有一个txt文本文件中有10万行记录(每行约10个汉字), 如何找出重复的行将其删除掉(保留一行)。 这个文本文件中每一个行是一个约10个字的记录 要求快速找出并删除重复的行。 我用的vc++里的控制台程序。 请求好的算法!谢谢。
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
15 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
deping_chen
2005-10-05
打赏
举报
回复
问题点数: 20 ,太少了。
deping_chen
2005-10-05
打赏
举报
回复
正则表达式匹配替换就OK了
==========================
难道要手工逐行输入字符串并执行查找替换?很慢的。
agaric
2005-10-05
打赏
举报
回复
一点点啦 10w行每行10个字,一共就100w个字,算是unicode也才200w个byte也才2M很多吗?不会多于10M的,pc上直接读取,可以保证速度
deping_chen
2005-10-05
打赏
举报
回复
可以这样:
待处理文件(假设叫C:\old.txt),创建一个新文件,假设叫C:\new.txt。
#include <windows.h>
#include <shlwapi.h>
#include <fstream>
using namespace std;
#pragma comment(lib, "shlwapi.lib")
#define INT_MAX 2147483647
//如果肯定老文件冗余行很多,MAX_LINE可以小些。
#define MAX_LINE 100000
#define BUF_SIZE 44
//保存新文件中各行的行号,该行号对应的字符串在新文件范围内按从小到大的顺序排列,
//其序号为数组的索引
int queue[MAX_LINE];
//新文件第索引行的文件位置
int linepos[MAX_LINE];
//新文件的行数
int totalsize = 0;
//读新文件
static ifstream rnewfile("C:\\new.txt");
inline void GetLine(int lineno, char* buffer, int bufsize)
{
rnewfile.seekg( linepos[lineno], ios_base::beg );
rnewfile.getline(buffer, bufsize);
}
bool IsLineRedundant(const char* buffer, int& order)
{
if(totalsize == 0)
{
order = 0;
return false;
}
//二分法判断该行是否冗余,如果不冗余,给出该行在新文件中的排序序号
int low = 0;
int high = totalsize-1;
char lineFromNew[BUF_SIZE];
while(high > low+1)
{
int mid = (high+low)/2;
GetLine(queue[mid], lineFromNew, BUF_SIZE);
int result = strcmp(buffer, lineFromNew);
if(result == 0)
return true;
if(result < 0)
high = mid - 1;
else
low = mid + 1;
}
GetLine(queue[low], lineFromNew, BUF_SIZE);
int result = strcmp(buffer, lineFromNew);
if(result == 0)
return true;
if(result < 0)
{
order = low;
return false;
}
if(high > low)
{
GetLine(queue[high], lineFromNew, BUF_SIZE);
result = strcmp(buffer, lineFromNew);
if(result == 0)
return true;
if(result < 0)
order = high;
else
order = high + 1;
}
else//high == low
{
order = low+1;
}
return false;
}
void DeleteRedundantLine()
{
//写新文件
ofstream newfile("C:\\new.txt");
//读老文件
ifstream oldfile("C:\\old.txt");
char buffer[BUF_SIZE];//最多存储21个汉字
int order;
while(!oldfile.eof())
{
oldfile.getline(buffer, BUF_SIZE);
if(IsLineRedundant(buffer, order))
continue;
//递增新文件中序号为order及以后的序号
memmove(&queue[order+1], &queue[order], (totalsize-order)*sizeof(int));
queue[order] = totalsize;//在新文件中第totalsize行按大小排序序号为order
linepos[totalsize] = newfile.tellp();
++totalsize;
newfile << buffer << endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
if(PathFileExists("C:\\new.txt") == FALSE)
{
MessageBox(NULL, "请先创建new.txt!", "错误", MB_OK|MB_ICONSTOP);
return 0;
}
DWORD start = GetTickCount();
DeleteRedundantLine();
DWORD end = GetTickCount();
printf("Time: %i milliseconds.\n", end-start);
return 0;
}
我用这个程序处理了81900行人名,大部分相同,花了2625毫秒。
dragonfly
2005-10-05
打赏
举报
回复
怪招建议:
使用ADO将TEXT文本作为数据库来访问。因为数据库读写已经作了一定的优化,所以暂时可以抛开这个优化的问题。只是不知道这样能不能够符合楼主的要求。
SydPink
2005-10-05
打赏
举报
回复
注意,HASH表中只保存行号,省去字符串拷贝的时间和空间。当确认发现重复的时候,
也不要立刻写文件删除行,记下此行应该被删除就好了,扫描完毕一次文件后,
已经找到全部要删除的行了,这个时候,从后向前删除行就好了。
这个方法应该很快的。最主要的循环比较每一行的时间已经被省略了。基本上
就是对 10W 行字符串求HASH的时间。虽然冲突很少(但是理论上无法避免),
所以当发生冲突的时候,必须比较两行,才能确信相同。
yjk
2005-10-05
打赏
举报
回复
在Unix下就用一句话:
sort file.txt | uniq
可以借鉴这个算法,首先对你的file.txt进行排序,将所有相同行调整在一
起,然后再删除
boylez
2005-10-05
打赏
举报
回复
baidu的程序设计大赛……哈哈
SydPink
2005-10-04
打赏
举报
回复
10W 条的话,看看这么做能不能快点?
做个30W的 字符串 HASH 表.表中每个元素保存的是一行的数据。逐行扫文件,
对每行求HASH值,如果表中当前位置为空,比较当前行和表中的这个位置
保存的行,如果这个位置不为空,则说明当前行和前面某行重复或者两行得到
相同的HASH值,现在比较一下是否相同,相同则删除,不相同则按你的HASH表的
冲突控制规则将这行也放进表中。继续下一行。
利用HASH函数的性质就很好判断是否重复了,30W的表对付10W数据,冲突几率
相当小,直接命中的纪律应该 》= 98%,所以,当冲突出现时候,98%的可能就是
重复行了。
struggle813
2005-10-04
打赏
举报
回复
正则表达式匹配替换就OK了
xlsue
2005-10-04
打赏
举报
回复
如果不能排序map或set也不能用。
xlsue
2005-10-04
打赏
举报
回复
如果可以排序的话,用vector比较块一些。话说回来,如果排序的话文件的顺序不是变了吗?
xyuanzhi
2005-10-04
打赏
举报
回复
如果用vector的话,每次写一条记录,都要遍历整个vector
还是建一个map,每次从旧的文件读一条记录,将它插入map,如果插入成功,将这条记录写入新文件,
如果已存在,则不写入.
fansy007
2005-10-04
打赏
举报
回复
一个vector抗不住,肯定要分段
healer_kx
2005-10-04
打赏
举报
回复
要是有数据库就好了.
就用Vector好了,不要用List,
数据结构课程设计.docx
数据结构课程设计.docx
xx关于行规行
约
贯彻落实情况自查报告知识.pdf
xx关于行规行
约
贯彻落实情况自查报告知识.pdf
安全行
约
车原型.rp
安全行
约
车原型.rp
宁波市二手车经纪行业协会行规行
约
.docx
宁波市二手车经纪行业协会行规行
约
.docx
信用社年度行规行
约
贯彻落实情况自查报告.pdf
信用社年度行规行
约
贯彻落实情况自查报告.pdf
C++ 语言
65,176
社区成员
250,526
社区内容
发帖
与我相关
我的任务
C++ 语言
C++ 语言相关问题讨论,技术干货分享,前沿动态等
复制链接
扫一扫
分享
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
请不要发布与C++技术无关的贴子
请不要发布与技术无关的招聘、广告的帖子
请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下
试试用AI创作助手写篇文章吧
+ 用AI写文章