2010-10-06 10 views
5

मुझे यह जानने की आवश्यकता है कि स्ट्रिंग में सभी वर्ण बराबर हैं (उसी वर्ण द्वारा गठित)। स्ट्रिंग के सभी तत्व किसी विशेष चार के बराबर होते हैं, तो फ़ंक्शन को सही या गलत वापस करना होगा।यह निर्धारित करने के लिए कि स्ट्रिंग में सभी वर्ण बराबर

मैंने यह फ़ंक्शन लिखा है जो अच्छी तरह से काम करता है, लेकिन मैं एक अधिक इष्टतम (सबसे तेज़) समाधान की तलाश में हूं, तारों में हजारों वर्ण हो सकते हैं।

function AllElementsAreEqual(Element:Char;Str:String):Boolean; 
var 
    i : Integer; 
begin 
Result:=True; 
if Str<>'' then 
    for i:=1 to Length(Str) do 
    if Str[i]<>Element then 
    begin 
     Result:= False; 
     exit; 
    end; 
end; 

अद्यतन अंत में बैरी केली सुझाव का उपयोग करने और inline निर्देश जोड़ने, प्रदर्शन में काफी सुधार किया गया था।

function AllElementsAreEqual(Const Element:Char;Str:String):Boolean;inline; 
type 
ArrayInt = Array of Integer; 
var 
    i : Integer; 
    Delta: Integer; 
    List : ArrayInt; 
    Test : Integer; 
begin 
    Result:=True; 
    Delta:=(Length(Str) mod 4); 
    if Delta<>0 then 
    Str:=Str+StringOfChar(Element,4-Delta); 
    Test:=Ord(Element) + Ord(Element) shl 8 + Ord(Element) shl 16 + Ord(Element) shl 24; 
    List:=ArrayInt(@(Str[1])); 

    for i:=0 to ((Length(Str) div 4)-1) do 
    if List[i]<>Test then 
    begin 
    Result:=False; 
    exit; 
    end; 
end; 

अद्यतन 2

मैं माफी चाहता हूँ, लेकिन मैं समाधान (एक बग के साथ) के एक पुराने कार्यान्वयन पोस्ट, अब तय हो गई है। बैरी सुझाव के बेहतर कार्यान्वयन के लिए The_Fox के लिए धन्यवाद।

+0

"===" ट्रिपल बराबर का उपयोग क्यों न करें जो इसके लिए उपयोग किया जाता है। तुलना करता है अगर यह बिल्कुल = करने के लिए है। डेटा प्रकार के साथ-साथ वर्ण – Val

+3

@ वैल की जांच करता है, क्योंकि डेल्फी के पास "===" कब होता है? क्या आप जावास्क्रिप्ट के साथ डेल्फी को भ्रमित कर रहे हैं? –

+0

मेरा बुरा मैं कुछ और सोच रहा था ... – Val

उत्तर

9

आप Element के साथ एक Integer मूल्य बनाने पर विचार कर सकता है, बार-बार 4 बार (के बाद से इस डेल्फी 7 में AnsiChar है) Ord(Element) + Ord(Element) shl 8 + Ord(Element) shl 16 + Ord(Element) shl 24 तरह स्थानांतरित कर दिया है, तो एक PIntegerArray (^array[0..MaxInt div 4 - 1] of Integer) और इस पर पाश करने के लिए स्ट्रिंग टाइपकास्ट Length(Str) div 4 बार, के रूप में की तुलना पात्रों के बजाय पूर्णांक। हालांकि आपको पिछले कुछ Length(str) mod 4 वर्ण मैन्युअल रूप से तुलना करने की आवश्यकता होगी।

+0

क्या इस तरह की चाल डेल्फी कंपाइलर इतनी तेजी से उपयोग करती है?;) –

+0

यह एक है स्ट्रिंग हैशिंग और तुलना के लिए यह चाल का उपयोग करता है, हां। –

0

शायद लक्ष्य चार बार बार बार बार स्ट्रिंग उत्पन्न करने के लिए StringOfChar का उपयोग करें, फिर char-by-char की तुलना करने के बजाय स्ट्रिंग तुलना करें।

(पता नहीं है कि यह वास्तव में तेज़ है; & देखें)।

-3

मैं क्या अपने कोड से समझ में आ से

Result:= False; 

": =" एक चर के मूल्य निर्दिष्ट किया जाता है। डेल्फी में 2 मानों की तुलना कैसे करते हैं?

+0

डेल्फी में ऑपरेटर: http://library.thinkquest.org/C006657/delphi/operators_in_delphi.htm –

+1

एक तार्किक तरीके से, बराबर बराबर के बराबर बराबर चिह्न के साथ, === या अन्य विषमता। : = आमतौर पर "असाइन किया गया है" या "बन जाता है" के रूप में पढ़ा जाता है। == "सी" (और मूल रूप से "बी") से आता है। हालांकि बीसीपीएल का इस्तेमाल किया गया: =, जो अल्गोल से आया था। इस अजीब फैसले के कारण (संभवतः थॉम्पसन और/या रिची द्वारा) हजारों कीड़े == –

+0

प्रतिभा के बजाय दुरुपयोग द्वारा बनाई गई हैं, मैं इसके बारे में कभी भी कैसे सोच सकता हूं। वाकई, मैंने कभी इतना शानदार जवाब नहीं देखा है, लेकिन आप कुछ चूक गए हैं, यानी, 'मार्क' को अंग्रेजी में * कोलन * कहा जाता है। मुझे उम्मीद है कि यहां कई लोग आपका जवाब वोट दे रहे हैं। > - ( – Vantomex

0

आप Select algorithm को जगह से बाहर तेज़ी से ढूंढने के लिए कार्यान्वित कर सकते हैं, इससे स्ट्रिंग "ट्रू" की गति में वृद्धि नहीं होगी, लेकिन इसे इसे कुछ तेज़ बनाना चाहिए।

0

स्ट्रिंग की लंबाई प्राप्त करें, स्ट्रिंग के आकार को स्मृति आवंटित करने के लिए GetMem का उपयोग करें। वांछित चार के साथ स्मृति भरें। फिर स्ट्रिंग और मेमोरी की तुलना करने के लिए तुलनामेम का उपयोग करें

6

आपने बैरी केली गलत के सुझाव को लागू किया। जब मैं डेल्फी 7 पर परीक्षण करते हैं, यह आपकी पहली कार्यान्वयन से भी धीमी है और यह गलत परिणाम देता है अगर आपके stringlength द्वारा 4.

मैं इस तार के साथ यह परीक्षण किया विभाज्य नहीं है: StringOfChar('c', 100000) + 'x'; और अपने नए फ़ंक्शन यह सच है AllElementsAreEqual('c', StringOfChar('c', 100000) + 'x') जबकि इसे झूठी वापसी करनी चाहिए।

आपका कार्यान्वयन धीमा है क्योंकि आप अपनी स्ट्रिंग को चार से विभाजित करने की कोशिश कर रहे हैं (जिसमें आप असफल हो जाते हैं, लेकिन आप स्वयं से यह पता लगा सकते हैं कि यह क्यों विफल हो जाता है) और इस प्रकार एक नई स्ट्रिंग तैयार कर रही है जिसके लिए मेमोरी आवंटन की आवश्यकता होती है जो महंगा है।

एक और खतरनाक चीज जो आप करते हैं वह गतिशील सरणी (पूर्णांक की सरणी) को स्ट्रिंग पर इंगित करती है। दोनों को refcounted हैं और इससे अजीब परिणाम हो सकते हैं। कृपया बैरी केली की सलाह का पालन करें और एक PIntegerArray का उपयोग करें!

मुझे लगता है कि बैरी केली इस का मतलब:

function AllElementsAreEqual(const aElement: Char; const aStr: string): Boolean; 
var 
    lIntArray: PIntegerArray; 
    i: Integer; 
    lTest: Integer; 
begin 
    Result := True; 
    lTest := Ord(aElement) + Ord(aElement) shl 8 + Ord(aElement) shl 16 + Ord(aElement) shl 24; 

    lIntArray := @aStr[1]; 
    for i := 0 to Length(aStr) div 4 - 1 do 
    if lIntArray[i] <> lTest then 
    begin 
     Result := False; 
     Exit; 
    end; 

    for i := Length(aStr) - (Length(aStr) mod 4) + 1 to Length(aStr) do 
    if aStr[i] <> aElement then 
    begin 
     Result := False; 
     Exit; 
    end; 
end; 

एनबी: आपका समारोह रिक्त स्ट्रिंग के लिए यह सच है देता है, वह ठीक है?

एनबी 2: कृपया बैरी केली के जवाब को अंक दें, न कि मेरा, क्योंकि यह वास्तव में एक oversized टिप्पणी है और जवाब नहीं है।

+0

+1 मुझे खेद है लेकिन कल रात मैंने विभिन्न कार्यान्वयन के साथ कई परीक्षण किए और मैंने प्रस्तावित समाधान (एक बग के साथ) का पुराना कार्यान्वयन पोस्ट किया, अब तय किया गया है। बैरी सुझाव के बेहतर कार्यान्वयन के लिए बहुत बहुत धन्यवाद। – Salvador

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

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