2010-04-28 67 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. 

有沒有一種方法可以做到這一點?德爾福 - 有沒有更好的方式來獲得州名縮寫

+0

你有一個錯字:「南卡羅琳」應爲「南卡羅來納」 – dthorpe 2010-04-28 22:22:51

+0

謝謝!我沒有看到... – Bill 2010-04-28 23:50:03

+1

你如何衡量「更好」?更快?短?可擴展?權威性? – 2010-04-29 05:01:49

回答

7

如果你在D2009或D2010,使用TDictionary<string, string>從Generics.Collections。聲明常量的數組,就像你擁有它,然後通過將每一對放入字典來設置字典。然後,只需使用字典的默認屬性來執行查找。

+1

我會建議兩個字典,每個函數一個。 – 2010-04-28 22:35:20

2

請注意,小寫(a)=小寫(b)比sameText(a,b)慢。

此外,還可以進一步由陣列作爲小寫與輸入轉換爲小寫以及存儲所述串只,然後在查找例程啓動加快該過程。然後你可以使用更快的函數sameStr(a,b)。但是,當然,如果找到匹配項,則需要使用首字母大寫來格式化它。這種加速方法對於如此小的字符串列表可能不是很重要。畢竟,美國沒有太多的州。

此外,你應該使用const的參數聲明函數,即寫

function getabb(const state:string):string; 

代替

function getabb(state:string):string; 

(除非你想在例行改變狀態)。

最後,您可以通過省略for循環的beginend來使代碼更加緊湊和易讀。

+1

沒有辦法,它是最快的(奇怪的是,你開始說它是最快的,然後繼續建議加速)。哈希表將會更快。事實上,兩個哈希表,一個用於'getabb'和一個用於'getstate',在啓動時動態增長,直到沒有衝突,甚至更快。可能更快仍然是一個特里結構。但是,如果你真的想把它最大化,直接編碼trie通路,這可以讓你優化像「密蘇里」和「密西西比」這樣的邊界情況。 – 2010-04-28 22:34:42

+0

@Marcelo:原則上意味着可能需要稍作修改,但主要想法是確定的。但是你是對的,它不是最快的,所以我會刪除那個不正確的部分。當我讀到問題的第一秒時,我認爲問題只是爲了獲得數組的第N個元素,即插入一個數字並獲取一個字符串。然後就不會有更快的方法。即使在我明白了真正的問題之後,這個結論仍然存在於我的腦海裏。 – 2010-04-28 22:43:10

8

這種數據應該被硬編碼嗎?
使用類似XML文件甚至是CSV文件會更好嗎?

或名稱值對,即IA =愛荷華
然後加載到TStringList中獲得

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

然後你只需要編寫一些搜索的值,比如逆向操作

//***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; 

我相當確信它不區分大小寫太

+2

+1;因爲使用帶名稱/值對的TStringList是一個很好的解決方案。我不明白你爲什麼被別人低估(這是不禮貌的,而不留下評論downvote)。 – 2010-04-29 06:26:17

+1

@Christopher Chase:爲什麼不能硬編碼?美國各州的名稱和縮寫現在已經固定了很長一段時間,並且在不久的將來可能不會改變。你把你自己的名字放在一個XML或CSV文件中,連同你的首字母縮寫嗎? (不是低調,因爲它是一個答案,儘管IMO不是一個好的答案,就好像在你的應用程序中添加一個RDBMS來存儲唯一的用戶登錄名和密碼 - 不必要的開銷,文件I/O和絕對沒有增益的代碼) – 2010-04-29 12:44:28

+1

@Ken White:尊重,我不同意。混合代碼和數據是icky。例如,dthorpe在這裏提到的「南卡羅來納州」的拼寫錯誤。如果那是在可執行文件中,則必須傳遞一個新的可執行文件,而如果數據存儲在單獨的位置(如中央數據庫)中,則錯誤可能更容易更正。在擁有數百個工作站的網站上部署大量的可執行文件並不是輕而易舉的事情。 – 2010-04-29 22:01:16

1

我就你的列表進行排序。這樣,您可以使用binary search來縮短查找時間。這一切都取決於你將要進行的迭代次數。大約50個項目看起來並不多,直到您在列表中迭代數千次才能查找列表中的最後一個項目。

而且你應該總是從你的循環,只要你得到一個匹配,如果你知道列表的其餘部分將不匹配保釋。

數組很好,根據您使用數據的方式,您可能需要添加一些也具有abbreviations(PR = PUERTO RICO,GU = GUAM等)的「區域」。