2010-04-28 13 views
5

const 
states : array [0..49,0..1] of string = 
(
('Alabama','AL'), 
('Montana','MT'), 
('Alaska','AK'), 
('Nebraska','NE'), 
('Arizona','AZ'), 
('Nevada','NV'), 
('Arkansas','AR'), 
('New Hampshire','NH'), 
('California','CA'), 
('New Jersey','NJ'), 
('Colorado','CO'), 
('New Mexico','NM'), 
('Connecticut','CT'), 
('New York','NY'), 
('Delaware','DE'), 
('North Carolina','NC'), 
('Florida','FL'), 
('North Dakota','ND'), 
('Georgia','GA'), 
('Ohio','OH'), 
('Hawaii','HI'), 
('Oklahoma','OK'), 
('Idaho','ID'), 
('Oregon','OR'), 
('Illinois','IL'), 
('Pennsylvania','PA'), 
('Indiana','IN'), 
('Rhode Island','RI'), 
('Iowa','IA'), 
('South Carolin','SC'), 
('Kansas','KS'), 
('South Dakota','SD'), 
('Kentucky','KY'), 
('Tennessee','TN'), 
('Louisiana','LA'), 
('Texas','TX'), 
('Maine','ME'), 
('Utah','UT'), 
('Maryland','MD'), 
('Vermont','VT'), 
('Massachusetts','MA'), 
('Virginia','VA'), 
('Michigan','MI'), 
('Washington','WA'), 
('Minnesota','MN'), 
('West Virginia','WV'), 
('Mississippi','MS'), 
('Wisconsin','WI'), 
('Missouri','MO'), 
('Wyoming','WY') 
); 
function getabb(state:string):string; 
var 
    I:integer; 
begin 
    for I := 0 to length(states) -1 do 
    if lowercase(state) = lowercase(states[I,0]) then 
    begin 
    result:= states[I,1]; 
    end; 
end; 
function getstate(state:string):string; 
var 
    I:integer; 
begin 
    for I := 0 to length(states) -1 do 
    if lowercase(state) = lowercase(states[I,1]) then 
    begin 
    result:= states[I,0]; 
    end; 
end; 
procedure TForm2.Button1Click(Sender: TObject); 
begin 
edit1.Text:=getabb(edit1.Text); 
end; 

procedure TForm2.Button2Click(Sender: TObject); 
begin 
edit1.Text:=getstate(edit1.Text); 
end; 

end. 

Bunu yapmanın bir yolu var mı?Delphi - Eyalet kısaltmalarından eyalet kısaltmaları almak için daha iyi bir yol var mı?

+0

Yazım hatası var: "Güney Carolin" "Güney Carolina" olmalı – dthorpe

+0

Teşekkürler! Bunu görmedim ... – Bill

+1

"Daha iyi" nasıl ölçülür? Daha hızlı? Daha kısa? Genişletilebilir? Yetkili? –

cevap

7

D2009 veya D2010 kullanıyorsanız, Generics.Collections ürününden TDictionary<string, string> kullanın. Sahip olduğunuz sabitler dizisini belirtin, ardından her bir çifti sözlüğe ekleyerek sözlüğünüzü ayarlayın. Ardından, aramalarınızı yapmak için yalnızca sözlüğün varsayılan özelliğini kullanın.

+1

Her fonksiyon için bir tane olmak üzere iki sözlük öneririm. –

2

Küçük harf (a) = küçük harf (b) 'nin aynı olduğundan daha az olduğuna dikkat edin. Metin (a, b). Ayrıca, dizideki dizeleri yalnızca küçük harf olarak saklayarak işlemi daha da hızlandırabilirsiniz, sonra da arama yordamında girişi küçük harfe dönüştürerek başlatırsınız. Daha sonra aynı daha hızlı olan aynı işlevi kullanabilirsin (tr, b). Ama elbette, bir eşleşme bulunduğunda, ilk harfleri büyük harfle yazarak biçimlendirmeniz gerekir. Bu hızlandırma yaklaşımı, böyle küçük bir dizeler listesi için büyük önem taşımamaktadır. Sonuçta, ABD'de çok fazla devlet yoktur. (Eğer rutin hal değiştirmek istemiyorsanız)

Ayrıca, yani

function getabb(const state:string):string; 

yerine

function getabb(state:string):string; 

ait yazma, const argümanları kullanarak işlevlerini ilan etmeli. Son olarak, for döngülerinin begin ve end numaralarını kaldırarak kodu daha küçük ve okunabilir hale getirebilirsiniz.

+1

Hiçbir şekilde en hızlısı yok (ve en hızlı olduğunu söyleyerek başlıyorsunuz ve sonra hız atlatmak için devam edin). Bir hash tablosu daha hızlı olacaktır. Aslında, başlangıçta dinamik olarak büyüyen ve hiçbir çarpışma olmadığında, daha hızlı olan iki karma tablo, biri “getabb” ve “gettate” için. Muhtemelen daha hızlı hala bir trie yapısıdır. Ancak, bunu gerçekten en çok yapmak istiyorsanız, "Missouri" ve "Mississippi" gibi kenar durumlarını optimize etmenizi sağlayan trie yollarını doğrudan kodlayın. –

+0

@Marcelo: Prensip olarak küçük değişikliklerin gerekebileceği, ancak ana fikrin iyi olduğu anlamına gelir. Ama sen haklısın, en hizli degil, bu yüzden bu yanlış parçayı kaldıracağım. Soruyu ilk okuduğumda, sorunun sadece bir dizinin Nth elemanını elde etmek olduğunu düşündüğüm, yani bir sayı girip bir dizge aldığımı düşündüm. Ve sonra daha hızlı bir yöntem olmazdı. Ve bir şekilde bu sonuç, gerçek problemi anladımdan sonra aklımda kalmıştır. –

8

Bu tür veriler kodlanmalı mı?
XML dosyası veya hatta bir CSV gibi bir şey kullanmak daha iyi olmaz mıydı?

Veya İsim Değer Çiftleri, yani IA = Iowa
o zaman tıpkı geriye çalışmak Değerlerini aramak için bir şey yazmaya gerek Sonra

States.Values['IA'] = 'Iowa'; 

almak için bir TStringList yüklenen

//***Untested*** 
//Use: NameOfValue(States, 'Iowa') = 'IA' 

function NameOfValue(const strings: TStrings; const Value: string): string; 
var 
    i : integer; 
    P: Integer; 
    S: string; 
begin 
    for i := 0 to strings.count - 1 do 
    begin 
    S := strings.ValueFromIndex[i]; 
    P := AnsiPos(strings.NameValueSeparator, S); 
    if (P <> 0) and (AnsiCompareText(Copy(S, 1, P - 1), Value) = 0) then 
    begin 
     Result := strings.Names[i]; 
     Exit; 
    end; 
    end; 
    Result := ''; 
end; 

Davaya duyarsız olduğundan eminim ki

+2

+1; İsim/değer çiftleriyle bir TStringList kullanmak iyi bir çözümdür. Neden başkaları tarafından reddedildiğini anlamıyorum (yorum bırakmadan reddetmek oldukça kaba). –

+1

@Christopher Chase: Neden kodlanmış DEĞİLDİR? ABD eyaletlerinin isimleri ve kısaltmaları şimdi oldukça uzun bir süredir sabit kalmıştır ve muhtemelen yakın gelecekte değişmeyecektir. Kendi adınızı bir XML veya CSV dosyasına, adlarınızla birlikte koyar mısınız? (IMO iyi olmasa da bir yanıt olduğu için reddetme değil. Uygulamanıza bir ve sadece kullanıcının oturum açma adını ve şifresini saklamak için bir RDBMS eklemek gibi - gereksiz ek yük, dosya G/Ç'si ve kesinlikle kazanç sağlamayan kod .) –

+1

@Ken White: saygılarımla, katılmıyorum. Kod ve veri karıştırmak çok kolay. Örneğin, dthorpe tarafından burada bahsedilen "Güney Carolina" için yazım hatası. Yürütülebilir durumda olsaydı, yeni bir yürütülebilir dosyanın teslim edilmesi gerekiyordu, oysa veriler merkezi bir veritabanı gibi ayrı bir yerde saklanırsa, hata daha kolay olabilir. Yüzlerce iş istasyonuna sahip sitelerde çok sayıda çalıştırıcının yerleştirilmesi, hafifçe yapılacak bir şey değildir. –

1

Listelerinizi sıralıyorum. Bu şekilde, arama sürelerini kısaltmak için binary search'u kullanabilirsiniz. Her şey, egzersiz yapacağınız iterasyonların sayısına bağlıdır. Listede son öğe için birkaç bin kez arama yaptığınızda, yaklaşık 50 öğe çok fazla görünmüyor.

Ayrıca, listenin geri kalanının eşleşmeyeceğini biliyorsanız, eşleşmelerden hemen sonra DAİMA kefaletlerinden kefalet etmelisiniz.

Diziler, verilerin nasıl kullanıldığına bağlı olarak, abbreviations (PR = PUERTO RICO, GU = GUAM, vb.) Içeren bazı "bölgeler" eklemeniz gerekebilir.

İlgili konular