Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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
3-63964
Ipx
2003-02-27 15:57
2003.03.20
Удаление строк из таблиц MSAccess с эффектом


1-64095
swamp
2003-03-10 12:44
2003.03.20
Разрушить компонент


6-64248
sergey2
2003-01-29 09:32
2003.03.20
Как в TWebBrowser отключить фрейм зная его номер?


6-64263
Шморгун Евгений
2003-01-31 16:15
2003.03.20
Internet Explorer и Delphi


3-64047
Лекс[КВ]
2003-02-27 11:01
2003.03.20
MasterSourse и многое другое:)))





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский