program Project12;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.Classes,
System.SysUtils,
Generics.Collections;
type
TTrieFilter =
class
private
FChildren: TObjectDictionary<Char, TTrieFilter>;
FIsWord: Boolean;
public
constructor Create;
destructor Destroy;
override;
procedure AddWord(
const Word:
string);
function ContainsWord(
const Word:
string): Boolean;
end;
constructor TTrieFilter.Create;
begin
FChildren := TObjectDictionary<Char, TTrieFilter>.Create([doOwnsValues]);
FIsWord := False;
end;
destructor TTrieFilter.Destroy;
begin
FChildren.Free;
inherited;
end;
procedure TTrieFilter.AddWord(
const Word:
string);
var
Node: TTrieFilter;
Ch: Char;
ChildNode: TTrieFilter;
begin
Node := Self;
for Ch
in Word
do
begin
if not Node.FChildren.TryGetValue(Ch, ChildNode)
then
begin
ChildNode := TTrieFilter.Create;
Node.FChildren.Add(Ch, ChildNode);
end;
Node := ChildNode;
end;
if not Node.FIsWord
then
Node.FIsWord := True;
end;
function TTrieFilter.ContainsWord(
const Word:
string): Boolean;
var
Node: TTrieFilter;
Ch: Char;
begin
Node := Self;
for Ch
in Word
do
begin
if Node.FChildren.ContainsKey(Ch)
then
begin
Node := Node.FChildren[Ch];
if Node.ContainsWord(Copy(Word, 2, Length(Word) - 1))
then
Exit(True)
else
Exit(False);
end;
end;
Result := Node.FIsWord;
end;
var
SLDaten, SLFilter, SLOutput: TStringList;
Trie: TTrieFilter;
I: Integer;
begin
try
SLFilter := TStringList.Create;
SLDaten := TStringList.Create;
SLOutput := TStringList.Create;
Trie := TTrieFilter.Create;
try
// beispielhaft deine filter liste
SLFilter.Add('
Sub1\Sub2\File1.exe');
SLFilter.Add('
FileX.exe');
SLFilter.Add('
Sub1\FileY.exe');
// hier die klasse mit den filtern befüllen
for I := 0
to Pred(SLFilter.Count)
do
Trie.AddWord(SLFilter[I]);
// das hier überspringen und gleich zum filtern weiter
// stell dir vor das ist deine dateiliste
// ps: die reihenfolge ist absolute irrelevant
SLDaten.Add('
c:\Hallo DieDolly\Sub1\Sub2\File1.exe');
SLDaten.Add('
WasAuchImmerFileX.exeHierSteht, es triggert');
SLDaten.Add('
\\\Sub2\FileY.exe');
// das ist das einzige was übrig bleibt
// Filter den input raus
for I := 0
to Pred(SLDaten.Count)
do
if not Trie.ContainsWord(SLDaten[I])
then
SLOutput.Add(SLDaten[I]);
// darstellen was übrig blieb
for I := 0
to Pred(SLOutput.Count)
do
WriteLn(SLOutput.Strings[I]);
finally
SLDaten.Free;
SLFilter.Free;
SLOutput.Free;
Trie.Free;
end;
ReadLn;
except
on E:
Exception do
Writeln(E.ClassName, '
: ', E.
Message);
end;
end.