Текущий архив: 2003.03.20;
Скачать: CL | DM;
Вниз
Подскажите как это сделать через CASE Найти похожие ветки
← →
Lego (2003-03-07 14:10) [0]У меня сделано пока что так:
var
s: string
if s="A" then result := 0;
if s="B" then result := 1;
if s="C" then result := 2;
...
if s="X" then result := 24;
if s="Y" then result := 25;
if s="Z" then result := 26;
Думаю все согласятся что это некрасиво :)
Хочется чтоб было через case s of... но чтото непоучается... возможно вообще использовать string для case?
Огромная просьба у меня инет по карточке и мало времени осталось, поэтому не флудите и неговорите загадками :)
← →
MBo (2003-03-07 14:15) [1]case s[1] of
или вообще Char, раз уж у тебя они односимвольные
← →
Anatoly Podgoretsky (2003-03-07 14:31) [2]Lego © (07.03.03 14:10)
Какая номер пропущен, A..Z = 0..25
Result := Ord(S[1]) - Ord(S["A"]);
← →
Lego (2003-03-07 14:36) [3]
> MBo © (07.03.03 14:15)
Нет они неодносимвольные... это я к примеру накидал что типа там стринги будут :)
> Anatoly Podgoretsky © (07.03.03 14:31)
Ошибся на 1 :)
Спасибо, пойду проверю :)
← →
Anatoly Podgoretsky (2003-03-07 14:40) [4]Поправка Result := Ord(S[1]) - Ord("A");
← →
Pat (2003-03-07 14:46) [5]>это я к примеру накидал что типа там стринги будут
case <ключ> of
<ключ> только перечисляемого типа...
← →
Lego (2003-03-07 15:05) [6]Чтото я всеравно немогу вкурить как это сделать...
Еще раз скажу что текст любой может быть:
var
s: string
if s="Apple" then result := 0;
if s="Автомобиль" then result := 1;
if s="God" then result := 2;
...
if s="Колбаса" then result := 24;
if s="Mouse" then result := 25;
if s="Текст" then result := 26;
так наверное понятнее что я хочу...
Пойду пока изучать дальше... если нетрудно то подкиньте в готовом виде это... а то чтото мозги щас похоже неварят вообще :(
← →
Smashich (2003-03-07 15:15) [7]лучче во первых так:
if s="Apple" then result := 0
else
if s="Автомобиль" then result := 1
else
if s="God" then result := 2
else
...
if s="Колбаса" then result := 24
else
if s="Mouse" then result := 25
else
if s="Текст" then result := 26;
а через case не решишь см. Pat © (07.03.03 14:46)
← →
Anatoly Podgoretsky (2003-03-07 15:19) [8]Э у тебя уже тут русские буквы появились, а это уже не 26 а больше, думаю, что далее речь зайде и о маленьких буквах и возможно о знаках препинания. В таком случае правильнее создать константный массив array[char] of Integer, в котором прописать свои весовые множители. Обращение будет такое Result := ar[S[1]];
← →
Lego (2003-03-07 15:25) [9]
> Smashich © (07.03.03 15:15)
Это не выход из положения...
> Anatoly Podgoretsky © (07.03.03 15:19)
Вот в томто и дело что текст заране указаный должен сверятся и если он такой то будет определенный результат...
Анатолий если нетрудно мкаленький пример... я думаю для вас это несложно а для меня просто потеря времени при каждой проверке ответов...
← →
han_malign (2003-03-07 15:28) [10]const cTemplate: array[0..26]of string=("Apple","Текст");
result:=0;
while((result<=26)and(s<>cTemplate[result])do inc(result);
if(result>26)then result:=-1;//not found
по скорости чуть медленнее прямого перебора, а вообще лучше пользоваться сортированным TStringLinst, он дихотомией ищет.
← →
AlexSV (2003-03-07 15:35) [11]Я думаю, что TStrings должен снять проблему:
StringStorage: TStrings;
Один раз :
StringStorage.Add("Автомобиль");
...
StringStorage.Add("Колбаса");
а потом:
StringStorage.IndexOf(MeStr);
← →
Anatoly Podgoretsky (2003-03-07 15:37) [12]Уточни задание, что то оно у тебя постоянно меняется, простыми человеческими слова, без выкрутасов и с примером. У меня теперь создалось впечатление, что у тебя список предопределенных слов.
← →
Lego (2003-03-07 15:44) [13]Есть список заранее известных слов, функция проверяет слова в тексте и если есть какоето слово из списка то возвращает опреденное значение...
в тех примерах что я давал вроде видно это...
← →
Anatoly Podgoretsky (2003-03-07 15:48) [14]Тогда самое простое
if S = "слово1" then Result := N1
else if S = "слово2" then Result := N2
...
else if S = "словоN" then Result := NN
else Result := -1;
← →
vuk (2003-03-07 15:59) [15]Вариант решения. Для каждого слова подсчитывается хеш-код(целое число), затем расписывается case по этим хеш-кодам. Работать будет быстро.
← →
Lego (2003-03-07 16:07) [16]
> Anatoly Podgoretsky © (07.03.03 15:48)
мда... похоже что так и прийдется сделать...
← →
vuk (2003-03-07 16:15) [17]И всё-таки, рассмотрите вариант с хешами.
CalcHash смотрите здесь:
http://delphibase.endimus.com/?action=viewfunc&topic=mathcalc&id=10092
function StrCalcHash( const S : string ) : integer;
begin
Result := CalcHash( pointer( S ), length( S ));
end;
var
i : integer;
begin
i := StrCalcHash(SomeString);
case i of
151:...;//хеш для строки "111"
158:...;//хеш для строки "222"
153:...;//хеш для строки "333"
end;
← →
Lego (2003-03-07 16:46) [18]
> vuk © (07.03.03 16:15)
Кстати очень похоже на то что мне нужно...
Но всетаки попробую сначала объяснить... точнее показать и спросить какбы вы это упростили?
function TForm1.TextIndex(s:string):integer;
begin
result := 0;
if s="Text1" then result := 1 else
if s="Text2" then result := 2 else
if s="Text3" then result := 3 else
if s="Text4" then result := 4 else
if s="Text5" then result := 5 else
if s="Text6" then result := 6 else
if s="Text7" then result := 7;
end;
Вот как это можно сделать покрасивее?
если бы у меня был не стринг а интигер то былобы проще... можно через case... а как тут?
вот думал чтоб получилось чтото типа этого...но так непроканает... вобщем если ктото понял о чем я то буду рад услышать еще варианты... нада пойти поспать может сам додумаюсь как сделать :) тяжко всетаки после 2 суток без сна :)
function TForm1.TextIndex(s:string):integer;
begin
case s of
"Text1": result := 1;
...
...
"TextN": result := N;
end;
end;
Кстати слово Text это просто для примера... как и говорилось выше текст любой указаный мной и количество может менятся... но больше чем 100 слов зарезервированых...
← →
Anatoly Podgoretsky (2003-03-07 16:50) [19]Покрасивее
else result := 0;
case of частный случай else if
← →
Sandman (2003-03-07 16:51) [20]case s[1] of
"a":begin
// слова, начинающиеся с буквы а
case s[2] of
"в":begin
// подозрение на "автомобиль" и "авария"
if s="автомобиль" then result := 1
else
if s="авария" then result := 2
else
result := -1;
end;
"г":begin
// подозрение на "агроном"
if s="агроном" then result := 3
else
result := -1;
end;
"б":
{ Ну и так далее... Программирование займет много времени. Правда, работать будет быстрее простого перебора вариантов }
← →
icWasya (2003-03-07 16:57) [21]
function GetChatKode(const s: string):Integer;
begin
If (Length(S)=1)and(S[1]>="A")and(S[1]<="Z")then
Result := Ord(S[1])-Ord{"A")
else Result:=-1;
end;
← →
vuk (2003-03-07 17:04) [22]to Lego:
Еще раз повторяю. Если все слова известны на момент компиляции, я посчитал бы для каждого слова хеш-код, и расписал бы case по результату вычисления. Как это делать я уже показал на примере.
← →
Anatoly Podgoretsky (2003-03-07 17:10) [23]Читабельность и управляемость проекта понизится, смысл есть для очень больших списков.
← →
vuk (2003-03-07 17:17) [24]Читаемость - да, но это достаточно легко поправить при помощи коментариев. А вот скорость работы вырастает значительно - гораздо меньше операций сравнения будет производиться. Да и упомянутые автором "больше чем 100 слов зарезервированых" - это как раз для такого подхода.
← →
Sandman (2003-03-07 17:21) [25]Если значений мало (до 100 или около того), то лучше всего использовать самую простую конструкцию if then else и не мучаться.
Если значений много, то нужно использовать простейшую таблицу в БД, состоящую из двух полей - текстового и integer, - и построить индекс по текстовому полю.
← →
Mike Kouzmine (2003-03-07 17:24) [26]В турбо-паскале была функция, которая возвращало целое, а принимала строку для быстрого сравнения оных, хотя я может ошибаюсь.
← →
vuk (2003-03-07 17:32) [27]to Sandman:
>лучше всего использовать самую простую конструкцию if then else
>и не мучаться.
Зависит от требований по скорости. По мне так посчитать хеш и расписать простой case проще, чем делать case по первой букве и кучу сравнений в каждой ветке, как у Вас написано.
>Если значений много, то нужно использовать простейшую таблицу в
>БД, состоящую из двух полей - текстового и integer, - и
>построить индекс по текстовому полю.
Можно, конечно, и штаны через голову надевать. Вы не задумывались, почему в различных компиляторах и парсерах используется именно вычисление хеш-кодов? А ведь там, зачастую, зарезервированных слов поменьше 100 бывает. Может им тоже БД при компиляции использовать посоветуете?
← →
Sandman (2003-03-07 18:32) [28]To vuk
Я имел ввиду первоначальную версию автора - это и был простейший if then else.
Зря Вы на меня обиделись - мой вариант является частным случаем Вашего хеширования, хеш-функция принимает значения первого символа строки :-)
Насчет БД.
Достаточно очевидно, что при очень большом количестве слов (1 миллион, например) БД будет наилучшим решением. Или Вы хотите попытаться изобрести велосипед, пытаясь найти наилучшую стратегию индексирования/хеширования? Пусть этим занимаются промышленные СУБД :)
← →
vuk (2003-03-07 23:07) [29]to Sandman:
>Зря Вы на меня обиделись
Это не ко мне, я такой ерундой, как обижание на кого-то не занимаюсь. :o)
>мой вариант является частным случаем Вашего хеширования
Нет. Хеш намного более избирателен.
>Достаточно очевидно, что при очень большом количестве слов (1
>миллион, например)
Условия задачи читаем, ага? Миллиона там не видно как-то... :o)
>Или Вы хотите попытаться изобрести велосипед
Как раз нет. То о чем я говорю для различных парсеров - стандартный подход.
← →
Lego (2003-03-08 03:21) [30]Вобщем я всетаки остановился на if then else... дело в том что это чат... текст сканится который прислан и потом по результу вбирается рисунок из имайдж листа... а в чате много слов небывает зарезервированых... 100-200 и небольше...
← →
Sandman (2003-03-10 10:33) [31]>мой вариант является частным случаем Вашего хеширования
Нет. Хеш намного более избирателен.
"Избирателен"? В смысле? Я имею в виду, понимаете ли Вы смысл хеширования? Его задача состоит в том, чтобы более менее равномерно распределить слова по категориям. Чем меньше разница в количестве слов между "максимально" и минимально населенной" областью, тем лучше. В идеале в каждую категорию входит одно и то же число слов. Слова, попадающие в одну категорию, все равно затем проверяются на совпадение. Хеш, не гарантирует того, что Вы ТОЧНО знаете слово, только потому что оно попало в данную категорию, особенно если множество слов бесконечно. Все равно после хеширования Вы вынуждены будете проверять слово на ПОЛНОЕ совпадение.
Вот Ваш пример, как он должен выглядеть.
function StrCalcHash( const S : string ) : integer;
begin
Result := CalcHash( pointer( S ), length( S ));
end;
var
i : integer;
begin
i := StrCalcHash(SomeString);
case i of
151://хеш для строки "111"
if SomeString = "111" then
Result := 1
else Result := -1;
158://хеш для строки "222"
if SomeString = "222" then
Result := 2
else Result := -1;
153://хеш для строки "333" и "835"
if SomeString = "333" then
Result := 3
else
if SomeString = "835" then
Result := 4
else Result := -1;
end;
Если на каждую букву приходится по 2-4 слова, то с учетом того, что на проверку первого символа уходит меньше времени, чем на вычисление значения хеш-функции, мой метод будет оптимальнее :)
Другое дело, что с помощью подбора правильной хеш-функции можно улучшить "равномерность" хеширования. Все-таки в русском языке количество слов, начинающихся на буквы "к" и, скажем, "щ", не совсем одного порядка.
← →
Alex44 (2003-03-10 11:17) [32]Pochemu ne sdelat" StringList?
(Pishu po pamyati...)
var Strings: TStringList;
function GetIndex(const S: string): Integer;
begin
with STrings do
if Find(S, Result) then
Result := Integer(Objects[Result])
else Result := -1;
end;
initialization
Strings := TStringList.Create;
STrings.Text := "text1"#10"text2"#10;
with Strings do begin
for I := 0 to Count - 1 do
Objects[I] := Pointer(I); // STore original indices
Sorted := True;
Sort; // DOn"t remember the argumets
end;
← →
vuk (2003-03-10 12:48) [33]to Sandman:
>"Избирателен"? В смысле?
В смысле если сделать нормальную хеш-таблицу, где группа будет выбираться сразу по индексу, без сравнений.
>мой метод будет оптимальнее
В принципе да, но он более труден для кодирования и еще труднее его модифицировать так, чтобы список строк и их идентификаторов был настраиваемым без перекомпиляции. Но это уже детали и к данной задаче они не относятся.
to Alex44:
>Pochemu ne sdelat" StringList?
Работать это будет на порядок медленнее чем все остальное.
← →
Sandman (2003-03-10 13:20) [34]vuk
>>"Избирателен"? В смысле?
>В смысле если сделать нормальную хеш-таблицу, где группа будет выбираться сразу по индексу, без сравнений.
Одно сравнение все-таки должно быть - ведь где гарантия, что у нас именно то слово, что мы ожидаем? Пользователь мог ввести ошибочное слово (не из нашего алфавита), которое попадает в одну категорию с каким-нибудь ожидаемым словом. В остальном я полностью согласен - при наличии функции, которая каждому ожидаемому слову ставит с соответствие уникальное значение, у нас будет максимальное быстродействие.
← →
vuk (2003-03-10 14:27) [35]>Одно сравнение все-таки должно быть
Как минимум. В принципе, при построении хеш-таблицы все равно возможны совпадения, поэтому в некоторых случаях сравнений все равно будет больше 1.
Страницы: 1 вся ветка
Текущий архив: 2003.03.20;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.008 c