加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 比较大文件

发布时间:2020-12-15 09:32:27 所属栏目:大数据 来源:网络整理
导读:我有一些文件(3-5),我需要比较: 文件1.txt有100万个字符串. 文件2.txt有1000万个字符串. 文件3.txt有500万个字符串. 所有这些文件都与文件keys.txt(万字符串)进行比较.如果当前打开的文件中的行与keys.txt中的行相同,请将此行写入output.txt(我希望您理解我
我有一些文件(3-5),我需要比较:
文件1.txt有100万个字符串.
文件2.txt有1000万个字符串.
文件3.txt有500万个字符串.
所有这些文件都与文件keys.txt(万字符串)进行比较.如果当前打开的文件中的行与keys.txt中的行相同,请将此行写入output.txt(我希望您理解我的意思).

我现在有:

function Thread.checkKeys(sLine: string): boolean;
var
  SR: TStreamReader;
  line: string;
begin
  Result := false;
  SR := TStreamReader.Create(sKeyFile); // sKeyFile - Path to file keys.txt
  try
    while (not(SR.EndOfStream)) and (not(Result))do
      begin
        line := SR.ReadLine;
        if LowerCase(line) = LowerCase(sLine) then
          begin
            saveStr(sLine);
            inc(iMatch);
            Result := true;
          end;
      end;
  finally
    SR.Free;
  end;
end;

procedure Thread.saveStr(sToSave: string);
var
  fOut: TStreamWriter;
begin
  fOut := TStreamWriter.Create('output.txt',true,TEncoding.UTF8);
  try
    fOut.WriteLine(sToSave);
  finally
    fOut.Free;
  end;
end;

procedure Thread.updateFiles;
begin
  fmMain.flDone.Caption := IntToStr(iFile);
  fmMain.flMatch.Caption := IntToStr(iMatch);
end;

并循环

fInput := TStreamReader.Create(tsFiles[iCurFile]);
    while not(fInput.EndOfStream) do
      begin
        sInput := fInput.ReadLine;
        checkKeys(sInput);
      end;
    fInput.Free;
    iFile := iCurFile + 1;
    Synchronize(updateFiles);

因此,如果我将这3个文件与文件key.txt进行比较,则需要大约4个小时.如何减少比较时间?

解决方法

一个简单的解决方案是使用关联容器来存储您的密钥.这可以提供有效的查找.

在Delphi中,您可以使用TDictionary< TKey,TValue>来自Generics.Collections.此容器的实现散列密钥并提供O(1)查找.

像这样声明容器:

Keys: TDictionary<string,Boolean>; 
// doesn't matter what type you use for the value,we pick Boolean since we
// have to pick something

像这样创建并填充它:

Keys := TDictionary<string,Integer>.Create;
SR := TStreamReader.Create(sKeyFile);
try
  while not SR.EndOfStream do
    Keys.Add(LowerCase(SR.ReadLine),True); 
    // exception raised if duplicate key found
finally
  SR.Free;
end;

然后你的检查功能变成:

function Thread.checkKeys(const sLine: string): boolean;
begin
  Result := Keys.ContainsKey(LowerCase(sLine));
  if Result then 
  begin
    saveStr(sLine);
    inc(iMatch);
  end;
end;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读