2010-04-28 30 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等)的“区域”。