Delphi - Является там лучшим способом получить аббревиатуры штата от имен состояния


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.

Существует ли bette способ сделать это?

5
задан Bill 28 April 2010 в 22:12
поделиться

4 ответа

Обратите внимание, что нижний регистр (a) = нижний регистр (b) медленнее, чем sameText (a, b).

Кроме того, вы можете еще больше ускорить процедуру, сохранив строки в массиве только в нижнем регистре, а затем в подпрограмме поиска начните с преобразования ввода в нижний регистр. Затем вы можете использовать еще более быструю функцию sameStr (a, b). Но, конечно, когда совпадение найдено, вам нужно отформатировать его, сделав начальные буквы заглавными. Такой подход к ускорению, вероятно, не очень важен для такого небольшого списка строк. В конце концов, в США не так уж много штатов.

Кроме того, вы должны объявлять функции, используя аргументы const, то есть писать

function getabb(const state:string):string;

вместо

function getabb(state:string):string;

(если вы не хотите изменить состояние в подпрограмме).

Наконец, вы можете сделать код более компактным и читаемым, опустив начало и конец циклов for .

2
ответ дан 18 December 2019 в 09:05
поделиться

Я бы отсортировал ваши списки. Таким образом, вы можете использовать бинарный поиск , чтобы сократить время поиска. Все зависит от количества итераций, которые вы будете выполнять. Около 50 элементов не кажутся большим количеством, пока вы не перебираете список несколько тысяч раз в поисках последнего элемента в списке.

Также вы должны ВСЕГДА отказываться от ваших циклов, как только вы получите совпадение, если вы знаете, что остальная часть списка не будет совпадать.

Массивы подходят, и в зависимости от того, как вы используете данные, вам может потребоваться добавить некоторые «территории», которые также имеют аббревиатуры (PR = PUERTO RICO, GU = GUAM и т. Д.) .

1
ответ дан 18 December 2019 в 09:05
поделиться

Должны ли такие данные быть жестко закодированы?
Не лучше ли использовать что-то вроде XML-файла или даже просто CSV.

Или пары имя-значение, т.е. IA=Iowa
, затем загрузить в 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;

Я уверен, что регистр не чувствителен

8
ответ дан 18 December 2019 в 09:05
поделиться

Если вы работаете на D2009 или D2010, используйте TDictionary из Generics.Collections. Объявите массив констант так, как он у вас есть, затем настройте свой словарь, поместив каждую пару в словарь. Затем просто используйте свойство словаря по умолчанию для выполнения поиска.

7
ответ дан 18 December 2019 в 09:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: