2012-05-14 15 views
10

मैं डेल्फी में एक फ़ंक्शन बनाना चाहता हूं जो दो तारों के विभिन्न स्तरों की गणना करता है। यदि दो तार बराबर हैं (मामले को अनदेखा कर रहे हैं), तो इसे 0 वापस करना चाहिए, लेकिन यदि वे बराबर नहीं हैं, तो इसे अलग-अलग वर्णों की संख्या वापस करनी चाहिए। वर्तनी जांचने के लिए यह फ़ंक्शन बहुत उपयोगी हो सकता है।मैं दो तारों के बीच एक अंतर की गणना कैसे कर सकता हूं?

function GetDiffStringLevel(S1,S2:string):Integer; 
begin 
    if SameText(S1,S2) then Exit(0); 
    // i want get different chars count 
end 

नमूने कोड:

Diff:=GetDiffStringLevel('Hello','Hello');// Diff:=0; 
Diff:=GetDiffStringLevel('Hello','2Hello');// Diff:=1; 
Diff:=GetDiffStringLevel('Hello','H2ello');// Diff:=1; 
Diff:=GetDiffStringLevel('Hello','Hello W');// Diff:=2; 
Diff:=GetDiffStringLevel('Hello','World');// Diff:=6; or 5 
+2

यह भी देखें: [स्ट्रिंग्स का पता लगाने के लिए नियमित रूप से आवश्यकता है जो समान हैं लेकिन समान नहीं हैं] (http://stackoverflow.com/q/10402858/576719)। –

उत्तर

12

फास्ट और कॉम्पैक्ट कार्यान्वयन।

सामान्य तारों के साथ स्मैशर के कार्यान्वयन के रूप में लगभग 3 गुना तेज। तारों में से एक खाली होने पर 100 से अधिक बार तेज है।

स्मैशर का कार्य मामला असंवेदनशील है, जो भी उपयोगी हो सकता है।

function LevenshteinDistance(const s, t: string): integer;inline; 
var 
    d : array of array of integer; 
    n, m, i, j : integer; 
begin 
    n := length(s); 
    m := length(t); 
    if n = 0 then Exit(m); 
    if m = 0 then Exit(n); 

    SetLength(d, n + 1, m + 1); 
    for i := 0 to n do d[i, 0] := i; 
    for j := 0 to m do d[0, j] := j; 

    for i := 1 to n do 
    for j := 1 to m do 
     d[i, j] := Min(Min(d[i-1, j]+1, d[i,j-1]+1), d[i-1,j-1]+Integer(s[i] <> t[j])); 

    Result := d[n, m]; 
end; 

नोट: inline निर्देश मेरी मशीन पर 70% से कम करने के लिए निष्पादन समय कम कर देता है, लेकिन केवल Win32 लक्ष्य मंच के लिए। यदि आप 64 बिट्स (डेल्फी एक्सई 2) को संकलित करते हैं, तो वास्तव में इनलाइनिंग इसे थोड़ा सा धीमा कर देती है।

7

क्या आप चाहते हैं अन्य, जहां एक संपादन या तो एक चरित्र प्रविष्टि, चरित्र विलोपन है में एक स्ट्रिंग को बदलने के लिए संपादन के Levenshtein distance (कम से कम संख्या के रूप में जाना जाता है या चरित्र प्रतिस्थापन)। विकिपीडिया साइट में एक छद्म कोड कार्यान्वयन है।

डेल्फी कार्यान्वयन:

function LevenshteinDistance(String1 : String; String2 : String) : Integer; 

var 
    Length1, Length2  : Integer; 
    WorkMatrix   : array of array of Integer; 
    I, J     : Integer; 
    Cost     : Integer; 
    Val1, Val2, Val3  : Integer; 

begin 
String1 := TCharacter.ToUpper (String1); 
String2 := TCharacter.ToUpper (String2); 
Length1 := Length (String1); 
Length2 := Length (String2); 
SetLength (WorkMatrix, Length1+1, Length2+1); 
for I := 0 to Length1 do 
    WorkMatrix [I, 0] := I; 
for J := 0 to Length2 do 
    WorkMatrix [0, J] := J; 
for I := 1 to Length1 do 
    for J := 1 to Length2 do 
    begin 
    if (String1 [I] = String2 [J]) then 
     Cost := 0 
    else 
     Cost := 1; 
    Val1 := WorkMatrix [I-1, J] + 1; 
    Val2 := WorkMatrix [I, J-1] + 1; 
    Val3 := WorkMatrix[I-1, J-1] + Cost; 
    if (Val1 < Val2) then 
     if (Val1 < Val3) then 
     WorkMatrix [I, J] := Val1 
     else 
     WorkMatrix [I, J] := Val3 
    else 
     if (Val2 < Val3) then 
     WorkMatrix [I, J] := Val2 
     else 
     WorkMatrix [I, J] := Val3; 
    end; 
Result := WorkMatrix [Length1, Length2]; 
end; 
+2

@ माजिद तहेरी: आपने एक ऐसे फ़ंक्शन के लिए कहा जो दो शब्दों के बीच अंतर की गणना करेगा, और स्मैशर का फ़ंक्शन आपके प्रश्न का उत्तर है। आपने कभी अपने प्रश्न में नहीं कहा * आप वास्तव में * फ़ंक्शन का उपयोग कैसे करेंगे। –

+2

@ माजिद तहेरी, आप [ले]] (http://stackoverflow.com/a/54798/576719) 'लेवेनशेटिन दूरी' के कार्यान्वयन का प्रयास कर सकते हैं। –

+0

@ एलयू आरडी, एडिटडिस्टेंस फ़ंक्शन बेहतर है। – MajidTaheri

संबंधित मुद्दे