2012-12-01 19 views
10

में मैं 3 सरणियों है, उदाहरण के लिए:तुलना सरणियों डेल्फी

const 
    A: Array[0..9] of Byte = ($00, $01, $AA, $A1, $BB, $B1, $B2, $B3, $B4, $FF); 
    B: Array[0..2] of Byte = ($A1, $BB, $B1); 
    C: Array[0..2] of Byte = ($00, $BB, $FF); 

वहाँ की तुलना करने और सही एक के सूचकांक प्राप्त करने के लिए, के बजाय 1 से प्रत्येक बाइट 1 जाँच करने का एक तरीका है? उदाहरण के लिए:

function GetArrayIndex(Source, Value: Array of Byte): Integer; 
begin 
.. 
end; 

GetArrayIndex(A, B); // results 3 
GetArrayIndex(A, C); // results -1 

अग्रिम धन्यवाद।

+4

यहां जवाब है, [क्या बाइट खोजने के लिए कोई "Pos" फ़ंक्शन है?] (Http://stackoverflow.com/q/4959566/576719)। –

+0

महान और तेज़ उत्तर। (मैंने कुछ भी नहीं ढूंढने के लिए लगभग 1 घंटे और आधा खर्च किया .. 5 '?)। धन्यवाद! मुझे उन कार्यों के उपयोग के लिए पॉइंटर्स के बारे में कुछ और अध्ययन करना है। –

+0

मैं अध्ययन के लिए एंड्रियास के उत्तर के एक पुनर्वित्तित संस्करण को पोस्ट करूंगा। –

उत्तर

12
function ByteArrayPos(const SearchArr : array of byte; const CompArr : array of byte) : integer; 
// result=Position or -1 if not found 
var 
    Comp,Search : AnsiString; 
begin 
    SetString(Comp, PAnsiChar(@CompArr[0]), Length(CompArr)); 
    SetString(Search, PAnsiChar(@SearchArr[0]), Length(SearchArr)); 
    Result := Pos(Search,Comp) - 1; 
end; 
+1

बहुत बढ़िया! ठीक वही जो मेरे द्वारा खोजा जा रहा था। –

+0

मुझे आश्चर्य है कि आपका उत्तर हाँ या नहीं है। मेरा मतलब है, क्या 'पॉस' प्रत्येक बाइट 1 से 1 * की जांच करता है? –

+0

हां और नहीं, निश्चित रूप से कहीं भी बाइट द्वारा चेक बाइट किया जाना है, लेकिन फिर से लागू करने की कोई आवश्यकता नहीं है। – bummi

7

एंड्रियास उत्तर here का एक पुनर्वित्तित संस्करण यहां दिया गया है।

function BytePos(const Pattern: array of byte; const Buffer : array of byte): Integer; 
var 
    PatternLength,BufLength: cardinal; 
    i,j: cardinal; 
    OK: boolean; 
begin 
    Result := -1; 
    PatternLength := Length(Pattern); 
    BufLength := Length(Buffer); 
    if (PatternLength > BufLength) then 
    Exit; 
    if (PatternLength = 0) then 
    Exit; 
    for i := 0 to BufLength - PatternLength do 
    if Buffer[i] = Pattern[0] then 
    begin 
     OK := true; 
     for j := 1 to PatternLength - 1 do 
     if Buffer[i + j] <> Pattern[j] then 
     begin 
      OK := false; 
      Break; 
     end; 
     if OK then 
     Exit(i); 
    end; 
end; 

begin 
    WriteLn(BytePos(B,A)); // 3 
    WriteLn(BytePos(C,A)); // -1 
    ReadLn; 
end. 

बम्स का जवाब पसंद करना है, हालांकि। काफी बेहतर।


टिप्पणियों में उल्लेख की गई एक टिप्पणी।

छोटे डेटासेट के लिए BytePosByteArrayPos से अधिक प्रदर्शन करता है, जबकि बड़े डेटासेट (10000 आइटम) के प्रदर्शन को उलट दिया जाता है।

यह 32-बिट मोड के लिए है, जहां असेंबलर Pos() सिस्टम फ़ंक्शन अनुकूलित करता है, बड़े डेटासेट के लिए सबसे अच्छा काम करता है।

हालांकि 64-बिट मोड में, कोई असेंबलर अनुकूलित पॉज़() फ़ंक्शन नहीं है। मेरे बेंचमार्क परीक्षण में, BytePos सभी प्रकार के डेटासेट आकारों के लिए ByteArrayPos से 4-6 गुना तेज है।


अद्यतन

बेंचमार्क परीक्षण XE3 साथ किया गया था।

परीक्षण के दौरान मैंने System.pas फ़ंक्शन Pos() में एक दोषपूर्ण purepascal पाश की खोज की।

एक सुधार अनुरोध जोड़ा गया है, QC111103, जहां प्रस्तावित कार्य लगभग 3 गुना तेज है।

मैंने उपरोक्त BytePos को थोड़ा सा अनुकूलित किया और इसे नीचे ByteposEx() के रूप में प्रस्तुत किया।

function BytePosEx(const Pattern,Buffer : array of byte; offset : Integer = 0): Integer; 
var 
    LoopMax : Integer; 
    OK   : Boolean; 
    patternP : PByte; 
    patStart : Byte; 
    i,j  : NativeUInt; 
begin 
    LoopMax := High(Buffer) - High(Pattern); 
    if (offset <= LoopMax) and 
    (High(Pattern) >= 0) and 
    (offset >= 0) then 
    begin 
    patternP := @Pattern[0]; 
    patStart := patternP^; 
    for i := NativeUInt(@Buffer[offset]) to NativeUInt(@Buffer[LoopMax]) do 
    begin 
     if (PByte(i)^ = patStart) then 
     begin 
     OK := true; 
     for j := 1 to High(Pattern) do 
      if (PByte(i+j)^ <> patternP[j]) then 
      begin 
      OK := false; 
      Break; 
      end; 
     if OK then 
      Exit(i-NativeUInt(@Buffer[0])); 
     end; 
    end; 
    end; 
    Result := -1; 
end; 
+0

हाँ, मैं मूल रूप से आपके पुन: कार्य किए गए फ़ंक्शन तरीके को समझ सकता हूं। आपके प्रयास के लिए बहुत बहुत धन्यवाद। –

+1

बुम्मी के कार्यान्वयन के रूप में पढ़ना उतना आसान नहीं है, लेकिन सिद्धांत रूप में यह बहुत तेज हो सकता है क्योंकि यह डेटा की प्रतिलिपि नहीं करता है। इसलिए इस के लिए भी +1। यदि यह अक्सर या बड़े डेटासेट पर उपयोग किया जाता है तो इससे कोई फर्क पड़ सकता है। हालांकि मैं वास्तव में अंतर को माप नहीं पाया था। –

+0

@ वाउटरवन निफ्टेरिक, मैंने एक छोटे डेटासेट (ऊपर एक) और एक बड़े डेटासेट (10000 तत्व) पर एक बेंचमार्क किया था। अंत में एक हिट के लिए, छोटे डेटासेट में 'बाइटपोस' 3 गुना तेज है, जबकि बड़े डेटासेट के लिए परिणाम विपरीत है। निष्कर्ष: 'बाइटएरेपॉस' में दो तारों का आवंटन छोटे डेटासेट के लिए प्रदर्शन जुर्माना देगा, जबकि अनुकूलित 'पॉस' सिस्टम बड़े डेटासेट के लिए एक्सेल करता है। –