Буквенный или цифровой введен символ

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Буквенный или цифровой введен символ

Сообщение Sergey_Afanasyev » 06.12.2014 18:55:53

Пользователь может ввести в окно ввода или фамилию или код сотрудника, который состоит из цифр. По первому введенному символу нужно определить как будет
производится поиск. Если это цифра – то по шифру. В программе написано

ss1 := TRIM(Edit1.Text);
ss2 := Utf8Copy(ss1,1,1);
if (ss2='0') or (ss2='1') or (ss2='2') or (ss2='3') or (ss2='4') or
(ss2='5') or (ss2='6') or (ss2='7') or (ss2='8') or (ss2='9') then
begin
// Поиск по шифру
End;

Как записать это более грамотно не перечисляя все цифры ?
Sergey_Afanasyev
новенький
 
Сообщения: 49
Зарегистрирован: 22.02.2012 19:30:27

Re: Буквенный или цифровой введен символ

Сообщение bormant » 06.12.2014 19:52:55

Код: Выделить всё
if ss1[1] in ['0'..'9'] then ...
Код: Выделить всё
if (ss1[1]>='0') and (ss1[1]<='9') then ...
Для ASCII это вполне работает.
Аватара пользователя
bormant
постоялец
 
Сообщения: 408
Зарегистрирован: 21.03.2012 11:26:01

Re: Буквенный или цифровой введен символ

Сообщение Sergey_Afanasyev » 06.12.2014 22:04:57

Большое спасибо. Оба варианта хорошо работают.
Sergey_Afanasyev
новенький
 
Сообщения: 49
Зарегистрирован: 22.02.2012 19:30:27

Re: Буквенный или цифровой введен символ

Сообщение Deimos » 06.12.2014 23:20:01

По моему мнению, первый пример затратит меньше времени выполнения (могу ошибаться / подскажите...), т..е более-актуален. Вопрос ответами исчерпан ))
Deimos
постоялец
 
Сообщения: 174
Зарегистрирован: 17.01.2010 00:31:30

Re: Буквенный или цифровой введен символ

Сообщение bormant » 07.12.2014 00:12:33

Deimos,
позволите поинтересоваться, на чем основано ваше мнение?
Вы провели сравнительные замеры производительности и/или посчитали такты в ассемблерном листинге?
У вас было еще какое-то обоснование, которое по непонятным причинам не было приведено?

Добавлено спустя 23 минуты 57 секунд:
Кстати, код, генерируемый 2.6.4 для b:=s[1] in ['0'..'9'], ничего общего с проверкой на принадлежность множеству не имеет, временное множество не конструируется, код действительно эффективнее 2-го случая:
Код: Выделить всё
; [5] b:=s[1] in ['0'..'9'];
      movzx   eax,byte ptr [U_P$PROGRAM_S+1]
      sub   eax,48
      cmp   eax,10
      jb   @@j5
@@j5:
      setc   byte ptr [U_P$PROGRAM_B]
сравните с:
Код: Выделить всё
; [6] b:=(s[1]>='0') and (s[1]<='9');
      mov   al,byte ptr [U_P$PROGRAM_S+1]
      cmp   al,48
      jae   @@j8
      jmp   @@j7
@@j8:
      mov   al,byte ptr [U_P$PROGRAM_S+1]
      cmp   al,57
      jbe   @@j6
      jmp   @@j7
@@j6:
      mov   byte ptr [U_P$PROGRAM_B],1
      jmp   @@j9
@@j7:
      mov   byte ptr [U_P$PROGRAM_B],0
@@j9:
С ключом -O1 ситуация улучшается:
Код: Выделить всё
; [6] b:=(s[1]>='0') and (s[1]<='9');
      mov   al,byte ptr [U_P$PROGRAM_S+1]
      cmp   al,48
      jnae   @@j7
      mov   al,byte ptr [U_P$PROGRAM_S+1]
      cmp   al,57
      jnbe   @@j7
      mov   byte ptr [U_P$PROGRAM_B],1
      jmp   @@j9
@@j7:
      mov   byte ptr [U_P$PROGRAM_B],0
@@j9:
С -O2 или -O3 всё ещё лучше:
Код: Выделить всё
; Var b located in register al
; [6] b:=(s[1]>='0') and (s[1]<='9');
      cmp   al,48
      jnae   @@j7
      cmp   al,57
      jnbe   @@j7
      mov   al,1
      jmp   @@j11
@@j7:
      mov   al,0
@@j11:
Аватара пользователя
bormant
постоялец
 
Сообщения: 408
Зарегистрирован: 21.03.2012 11:26:01

Re: Буквенный или цифровой введен символ

Сообщение Ism » 08.12.2014 00:15:24

Ism
энтузиаст
 
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Re: Буквенный или цифровой введен символ

Сообщение SSerge » 08.12.2014 06:01:07

бог мой! Уже регэкспы бедняге предлагаются :mrgreen:
Коллеги, почему по этому случаю позабыто самое традиционное?

if (pos(ss2,'0123456789')<>0) ...

или еще идеологически правильнее:

if (utf8pos(ss2,'0123456789')<>0) ...
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Буквенный или цифровой введен символ

Сообщение pda » 08.12.2014 15:10:44

SSerge писал(а):Коллеги, почему по этому случаю позабыто самое традиционное?

Потому что за такой код, как и за регулярки, при решении подобной задачи, надо хватать такого "программиста" и депортировать его обратно в Индию.
Аватара пользователя
pda
постоялец
 
Сообщения: 303
Зарегистрирован: 27.05.2005 19:59:53

Re: Буквенный или цифровой введен символ

Сообщение Deimos » 08.12.2014 15:45:59

bormant писал(а):Deimos,
позволите поинтересоваться, на чем основано ваше мнение?
Вы провели сравнительные замеры производительности и/или посчитали такты в ассемблерном листинге?
У вас было еще какое-то обоснование, которое по непонятным причинам не было приведено?



Замечу свое-же
могу ошибаться


Нет, замеров я не делал.

Исходил из логики, что в первом случае используется одна операция проверки вхождения в последовательность, во втором - 10 операций сравнений. Тактов, опять-же, не считал... Как конкретно реализованы оба эти варианта в компиляторе, я не знаю, исходя из чего я и упомянул, что это мое мнение...

bormant писал(а):Кстати, код, генерируемый 2.6.4 для b:=s[1] in ['0'..'9'], ничего общего с проверкой на принадлежность множеству не имеет, временное множество не конструируется


прочел позднее ответа. Информация полезна - спасибо.
Deimos
постоялец
 
Сообщения: 174
Зарегистрирован: 17.01.2010 00:31:30

Re: Буквенный или цифровой введен символ

Сообщение SSerge » 08.12.2014 15:59:54

pda писал(а):Потому что за такой код, как и за регулярки, при решении подобной задачи, надо хватать такого "программиста" и депортировать его обратно в Индию.


формально он ничем не хуже решения из самого первого поста темы :D

Истинно индусский код - он не такой, а что-то типа:

Код: Выделить всё
i:byte^;

i:=(pbyte)@ss1;
if (i>=48 and i<(48+10)) then ...
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Буквенный или цифровой введен символ

Сообщение VirtUX » 08.12.2014 17:55:07

2 SSerge
Вы дважды уже допускаете ошибку (в двух последних комментариях), и поэтому, лично я, поддерживаю:
pda писал(а):депортировать его обратно в Индию

P.S. Ничего личного...
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Буквенный или цифровой введен символ

Сообщение скалогрыз » 08.12.2014 18:33:07

оставлю это здесь для коллекции решений... :mrgreen:
Код: Выделить всё
var
  Nums : array [Char] of boolean;
..

if Nums[ss2[1]] then
begin
// Поиск по шифру
End;

...
procedure InitNumsTable;
var
  i : char;
begin
  FillChar(Nums, sizeof(Nums), 0);
  for i:='0' to '9' do
    Nums[i]:=true;
end;

initialization
  InitNumsTable;

todo: заменить динамическую инициализацию Nums (через InitNumsTable) - статической и сделать его const а не var!
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Буквенный или цифровой введен символ

Сообщение Ism » 09.12.2014 00:00:23

pda писал(а):Потому что за такой код, как и за регулярки, при решении подобной задачи, надо хватать такого "программиста" и депортировать его обратно в Индию.

Ну как сказать, в коде предпочтительней понятность его чтения, и вариант
SSerge писал(а):pos(ss2,'0123456789')<>0) ...
не так уж плох, так как работает с любыми символами и кодировками
Regexp же способен заменить тонну кода одним выражением, кроме того это стандарт и может использовать уже существующие выражения, такие, как проверка email
Ism
энтузиаст
 
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Re: Буквенный или цифровой введен символ

Сообщение pda » 09.12.2014 00:16:36

Изображение
Аватара пользователя
pda
постоялец
 
Сообщения: 303
Зарегистрирован: 27.05.2005 19:59:53

Re: Буквенный или цифровой введен символ

Сообщение SSerge » 09.12.2014 06:15:03

Вот еще один способ (2.7.x); работающий, кстати. кто больше?

Код: Выделить всё
{$mode objfpc}
{$H+}
uses character;
function StartsAsDigit(s:string):boolean;
begin
   if (length(s)<1) then
      result:=FALSE
   else
     result:=TCharacter.IsDigit(s[1]);
end;
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 236

Рейтинг@Mail.ru
cron