Данный форум может являться полигоном для набора некоторого опыта, который на следующем этапе будет являться уже и знанием.
Если им правильно пользоваться.
А по факту - вещь удивительная. Начинали с неких ТераОпов, даже дискутировали о названии сего дикого числа.
А кончили, при сравнении RND_20 и RND_19 (1М сравниваем с 512К) -- 32-мя КилоОпами за 0.18 сек.
SearchMatches.png
Мой код, переделанный под 3-байтную индексацию, и ранее инжектированный в схему Леонида
Add(Label,1824696,427,91)
{
@Hint=#26:А чтобы никто не догадался|
Width=100
Height=286
Align=1
Caption=""
AutoSize=1
AddHint(-59,-23,158,13,@Hint)
}
Add(Button,6300579,35,35)
{
Left=10
Top=5
Width=70
Caption="Open 2 files"
link(onClick,908814:doExecute,[])
}
Add(Edit,6253556,280,84)
{
Left=65
Top=40
Width=25
Text="5"
DataType=2
}
Add(Label,5760286,280,35)
{
Left=7
Top=35
Width=61
Height=32
Caption="Number of\r\nbytes >="
AutoSize=1
Alignment=2
}
Add(Button,13033686,35,161)
{
Left=15
Top=125
Caption="Search"
link(onClick,6984947:doEvent1,[])
}
Add(ODialog,908814,84,35)
{
Title="Open first file"
link(onExecute,14252828:doEvent1,[])
}
Add(ODialog,9007154,84,84)
{
Title="Open second file"
link(onExecute,4645375:doEvent1,[])
}
Add(Hub,14252828,126,35)
{
OutCount=3
link(onEvent1,14151222:doOpen,[])
link(onEvent2,14151222:doClose,[])
link(onEvent3,9007154:doExecute,[(151,55)(151,76)(74,76)(74,90)])
}
Add(FileStream,14151222,168,35)
{
link(onLoad,9951475:doCopy,[])
}
Add(FileStream,6090657,168,84)
{
link(onLoad,7759878:doCopy,[])
}
Add(Button,5547259,35,217)
{
Left=15
Top=202
Caption="Save"
link(onClick,9381149:doExecute,[])
}
Add(InlineCode,9739546,224,182)
{
WorkPoints=#31:doSearchStream=Поиск совпадений|
EventPoints=#6:onTime|48:onRes=Позиции начала совпадения, разделитель ";"|
VarPoints=#8:compares|
DataPoints=#46:Stream1=Данные 1-го файла (нужен MemoryStream)|46:Stream2=Данные 2-го файла (нужен MemoryStream)|35:Num=Количество байтов для сравнения|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|21:uses kol,Share,Debug;|0:|4:type|29: THiAsmClass = class(TDebug)|11: private|34: Entry,Tail:Array of integer;|16: dbg:int64;|10: public|45: onTime,onRes:THI_Event; //Events|44: Stream1,Stream2,Num:THI_Event; //Datas|25: constructor Create;|60: procedure doSearchStream(var _Data:TData; Index:word);|54: procedure compares(var _Data:TData; Index:word);|6: end;|0:|14:implementation|0:|31:constructor THiAsmClass.Create;|5:begin|12: inherited;|29: SetLength(Entry, $1000000);|4:end;|0:|37:procedure THiAsmClass.doSearchStream;|15:var ST:PStream;|14: F1,F2:PChar;|43: _Len1,_Len2,_Len, i, j,k,_Min,_A:integer;|11: s:string;|5:begin|35: ST := ReadStream(_Data, Stream1);|24: if ST = nil then Exit;|19: _Len1 := ST.Size;|18: F1 := ST.Memory;|35: ST := ReadStream(_Data, Stream2);|24: if ST = nil then Exit;|19: _Len2 := ST.Size;|18: F2 := ST.Memory;|82: _Min := ReadInteger(_Data, Num, 4); //Минимальное количество совпадающих байт|29: if _Min < 3 then _Min := 3;|59: FillChar(Entry[0], sizeof(Entry[0])*Length(Entry), #$FF);|27: SetLength(Tail, _Len2-2);|30://---Файл второй -- индексация|22: _hi_OnEvent(onTime);|21: _Len:=_Len2 - _Min;|33: for i := _Len downto 0 do begin|61: _A :=ord(F2[i])shl 16 + ord(F2[i+1])shl 8 + ord(F2[i+2]);|25: Tail[i] := Entry[_A];|18: Entry[_A] := i|6: end;|25://---Файл первый -- поиск|22: _hi_OnEvent(onTime);|23: _Len := _Len1 - _Min;|11: dbg := 0;|29: for i := 0 to _Len do begin|68: j := Entry[ord(F1[i])shl 16 + ord(F1[i+1])shl 8 + ord(F1[i+2])];|25: while j >= 0 do begin|16: inc(dbg); |90: _A := 3; //Три первых байта совпадают по определению|82: while ((i+_A)<_Len1)and((j+_A)<_Len2) do //Проверяем выход за размеры файлов|93: if F1[i+_A]=F2[j+_A] then inc(_A) //Увеличиваем кол-во совпавших байт на единицу|101: else break; //Если уже не совпадают - длина совпадений уже найдена|105: if _A>=_Min then begin //Если не менее установленного, выводим длину, позиции, и HEX - на индикацию|60: s := int2str(_A)+';'+int2str(i)+';'+int2str(j)+';'; |63: for k := 0 to _A-1 do s := s + int2hex(ord(F1[i+k]),2);|30: _hi_OnEvent(onRes, s);|10: end;|19: j := Tail[j];|8: end;|6: end;|4:end;|0:|31:procedure THiAsmClass.compares;|5:begin|21: dtReal(_Data, dbg);|4:end;|0:|4:end.|
link(onTime,5441784:doWork2,[])
link(onRes,11582479:doAdd,[])
link(Stream1,9951475:Stream,[])
link(Stream2,7759878:Stream,[])
link(Num,6253556:Text,[(244,131)(286,131)])
}
Add(Hub,4645375,126,84)
{
link(onEvent1,6090657:doOpen,[])
link(onEvent2,6090657:doClose,[])
}
Add(LED,15486262,427,147)
{
Left=30
Top=157
Height=32
Shape=1
}
Add(Hub,6984947,119,161)
{
OutCount=4
link(onEvent1,15486262:doOn,[])
link(onEvent2,12086:doStart,[(340,174)(340,181)])
link(onEvent3,11582479:doClear,[(214,181)(214,202)])
link(onEvent4,11956262:doStart,[])
}
Add(SDialog,9381149,84,217)
{
Filter="TXT|*.txt"
link(onExecute,11582479:doSave,[])
}
Add(Thread,11956262,168,182)
{
Delay=0
FastStop=0
link(onExec,9739546:doSearchStream,[])
link(onSyncExec,15749816:doData,[(207,195)(207,244)])
}
Add(TimeCounter,12086,350,175)
{
link(onStop,3828704:doEvent1,[])
}
Add(StrList,11582479,280,189)
{
Point(doSave)
}
Add(FormatStr,13053289,420,252)
{
DataCount=5
Mask="Found %1 (%5) matches in (%2,%3,%4) мs"
link(onFString,5052926:doWork2,[])
link(Str1,11582479:Count,[(426,236)(293,236)])
link(Str2,16099733:Value1,[])
link(Str3,16099733:Value2,[])
link(Str4,16099733:Value3,[])
}
Add(StringTable,4173653,350,266)
{
Left=100
Width=322
Height=261
Align=5
Font=[Lucida Console,8,0,0,0]
Columns=#18:Matches length=100|21:Pos in first file=100|22:Pos in second file=100|18:Matches in HEX=200|
Grid=0
ColumnClick=1
Point(doSortDigit)
Point(onColumnClick)
link(onColumnClick,4173653:doSortDigit,[(389,279)(389,307)(340,307)(340,293)])
}
Add(ArrayEnum,156378,294,266)
{
link(onItem,4173653:doAdd,[])
link(Array,11582479:Array,[])
}
Add(Hub,2244651,266,238)
{
OutCount=5
link(onEvent1,5441784:doWork3,[(319,244)])
link(onEvent2,15486262:doOff,[(389,251)(389,160)])
link(onEvent3,13053289:doString,[])
link(onEvent4,4173653:doClear,[(333,265)(333,279)])
link(onEvent5,156378:doEnum,[])
}
Add(MemoryStream,9951475,224,35)
{
}
Add(MemoryStream,7759878,231,84)
{
}
Add(HubEx,5441784,315,182)
{
link(onEvent,12086:doStop,[])
}
Add(HubEx,5052926,476,252)
{
link(onEvent,5996595:doCaption,[])
}
Add(MemFIFO,16099733,427,189)
{
Count=3
}
Add(MainForm,5996595,497,252)
{
Width=438
}
Add(Hub,3828704,399,182)
{
link(onEvent1,5052926:doWork1,[(480,188)])
link(onEvent2,16099733:doValue,[])
}
Add(DoData,15749816,224,238)
{
link(onEventData,2244651:doEvent1,[])
link(Data,9739546:compares,[])
}
Такое не часто случается, однако.