IPB
ЛогинПароль:

> ВНИМАНИЕ!

Прежде чем задать вопрос, смотрите FAQ.
Рекомендуем загрузить DRKB.

 
 Ответить  Открыть новую тему 
> Поиск числа в строке
marwell
сообщение 13.10.2011 19:10
Сообщение #1


Бывалый
***

Группа: Пользователи
Сообщений: 198
Пол: Мужской

Репутация: -  1  +


Добрый вечер
Собственно, само задание: вводится строка, найти в этой строке первое число (может быть с запятой) (учитываются и знаки '+-') в общем из строки типа +-+--+-+-123,345ывыва6254в программа должна вывести -123,345
со знаками разобрался, не получается с запятыми. Чувствую, надо полностью переделывать условие
а, да. совсем забыл. Нельзя использовать стандартные процедуры преобразования типов

procedure TForm1.Button1Click(Sender: TObject);
var s,s2,s3: string;
    m,m2,z: set of char;
  i: integer;
begin
Label1.Caption:='';
s:=Edit1.Text;
m:=['0'..'9', '+', '-'];
z:=['+','-'];
m2:=['0'..'9', '.', ','];
s2:='';
for i:=1 to Length(s) do begin
if s[i] in m then begin
if (s[i+1] in m2) and not (s[i+1] in z)  then
                begin
                s3:=s[i+1];
                s2:=s2+s[i];
                if not (s[i+2] in m2) then break;
                end
                else continue;
end;

end;
Label1.Caption:=s2+s3;
end;
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 14.10.2011 12:12
Сообщение #2


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Открываешь книгу Р. Хантера "Проектирование и конструирование компиляторов" на стр. 45-46, и смотришь, как строится конечный автомат, распознающий в строке вещественное число. Небольшая доработка - и получаешь функцию, которая вернет тебе первое вхождение вещественного числа в строке.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
marwell
сообщение 14.10.2011 14:04
Сообщение #3


Бывалый
***

Группа: Пользователи
Сообщений: 198
Пол: Мужской

Репутация: -  1  +


Цитата(IUnknown @ 14.10.2011 12:12) *

Открываешь книгу Р. Хантера "Проектирование и конструирование компиляторов" на стр. 45-46, и смотришь, как строится конечный автомат, распознающий в строке вещественное число. Небольшая доработка - и получаешь функцию, которая вернет тебе первое вхождение вещественного числа в строке.

спасибо, попробую
а так задачу решил, код вышел длинный и некрасивый, но работающий
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
marwell
сообщение 14.10.2011 14:04
Сообщение #4


Бывалый
***

Группа: Пользователи
Сообщений: 198
Пол: Мужской

Репутация: -  1  +


О_о почему то мое сообщение отправилось два раза

Сообщение отредактировано: marwell - 14.10.2011 14:05
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
marwell
сообщение 15.10.2011 12:02
Сообщение #5


Бывалый
***

Группа: Пользователи
Сообщений: 198
Пол: Мужской

Репутация: -  1  +


вот что получилось с использованием конечного автомата

procedure TForm1.Button1Click(Sender: TObject);
type Mtype=(H,A,B,C,D,E,F,S);
var S1,S2: string;
i: integer;
q: Mtype;
begin
S1:=Edit1.text+' ';
i:=1;
S2:='';
q:=H;
Repeat
case q of
  H: case S1[i] of
      '.': begin
        q:=B;
        S2:=S2+S1[i];
        Inc(i);
        end;
      '+','-': begin
          q:=A;
          S2:=S2+S1[i];
          Inc(i);
          end;
      '0'..'9': begin
          q:=C;
          S2:=S2+S1[i];
          Inc(i);
        end;
       else begin
       q:=H;
       Inc(i);
      end;
    end;
  B: case S1[i] of
      '0'..'9': begin
          q:=D;
          S2:=S2+S1[i];
          Inc(i);
      end;
       else begin
       q:=H;
       S2:='';
      end;
    end;
  A: case S1[i] of
      '0'..'9': begin
          q:=C;
          S2:=S2+S1[i];
          Inc(i);
      end;
       else begin
       q:=H;
       S2:='';
      end;
    end;
  C: case S1[i] of
    '.': begin
          q:=F;
          S2:=S2+S1[i];
          Inc(i);
      end;
    '0'..'9': begin
          q:=C;
          S2:=S2+S1[i];
          Inc(i);
        end;
      else q:=S;
    end;
  F: case S1[i] of
    '0'..'9': begin
          q:=D;
          S2:=S2+S1[i];
          Inc(i);
      end;
    else q:=S;
    end;
  D: case S1[i] of
    '0'..'9': begin
          q:=D;
          S2:=S2+S1[i];
          Inc(i);
        end;
      else q:=S;
    end;
end;
Until q=S;
Label1.Caption:=S2;

end;


а вот как было до этого

procedure TForm1.Button1Click(Sender: TObject);
var s,s2: string;
    m,m2,m3,m4,m5,z: sss;
  i,k,j,n: integer;
  f,f2: boolean;
begin
Label1.Caption:='';
s:=Edit1.Text;
m:=['0'..'9', '+', '-'];
z:=['+','-'];
m2:=['0'..'9', '.', ','];
m3:=[',', '.'];
m4:=['0'..'9', '+', '-', ',', '.'];
m5:=['0'..'9'];
s2:='';
i:=0;
n:=0;
k:=0;
f:=False;
f2:=False;
Repeat
Inc(i);
if (S[i] in m) then k:=i;
if ((S[i] in z) and (S[i+1] in m5)) or ((S[i] in m5) and (S[i+1] in m5)) then f:=True;
if S[i] in m5 then f2:=True;
until (((S[i] in m) and (pr(S[i], S[i+1],z)=True)) and (f=True)) or (i=Length(s)) or f2=True;

f:=False;

for j:=k to Length(s) do
begin
if s[j] in m then begin
f:=True;
Break;
end;
end;

k:=j;

if f=true then begin
for j:=k to Length (S) do
begin
 if S[j] in m4 then
  begin
  if (S[j]=',') or (S[j]='.') then n:=n+1;
   if (n=1) then if (S[j] in m5) or (S[j+1] in m5) or (j=Length(S)) then s2:=s2+s[j]
                                    else break;
   if (n=0) and (S[j] in m) then s2:=s2+s[j];
   if S[j] in m3 then begin
    if pr(S[j],S[j+1],m3)=False then Break; end;
  end;
 if (not (S[j+1] in m2)) or (n>1) then Break;
end;
end;

f:=False;

for i:=1 to Length(s2) do begin
if s2[i] in m5 then begin
f:=True;
Break;
end;
end;

if (s2='') or (f=False) then Label1.Caption:='net chisla'
          else Label1.Caption:=s2;
end;


разница, мягко говоря, огромная smile.gif


Добавлено через 1 мин.
IUnknown, спасибо за совет smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 15.10.2011 15:24
Сообщение #6


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Для твоего случая достаточно:
   i := 1;
   S2 := '';
   q := H;
   repeat
      case q of
         H:
         begin
            case S1[i] of
               '.':
               begin
                  q:=B;
                  S2:=S2+S1[i];
               end;
               '+', '-':
               begin
                  q:=A;
                  S2:=S2+S1[i];
               end;
               '0'..'9':
               begin
                  q:=C;
                  S2:=S2+S1[i];
               end;
               else q:=H;
            end; // case
            Inc(i); // Это делается всегда
         end;

         A, B:
         case S1[i] of
            '0'..'9':
            begin
               q:=Succ(Succ(q)); // Вместо case A => q := C и case B => q := D
               S2:=S2+S1[i];
               Inc(i);
            end;
            else
            begin
               q:=H;
               S2:='';
            end;
         end;


         C:
         case S1[i] of
            '.':
            begin
               q:=F;
               S2:=S2+S1[i];
               Inc(i);
            end;
            '0'..'9':
            begin
               q:=C;
               S2:=S2+S1[i];
               Inc(i);
            end;
            else q:=S;
         end;

         F, D: // Эти 2 ветки у тебя вообще идентичные
         case S1[i] of
            '0'..'9':
            begin
               q:=D;
               S2:=S2+S1[i];
               Inc(i);
            end;
            else q:=S;
         end;

      end;
   until q = S;
я просто чуть-чуть упростил твой же код, объединил одинаковые (и почти одинаковые, как в случае q=A и q=B) ветки...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
marwell
сообщение 15.10.2011 19:55
Сообщение #7


Бывалый
***

Группа: Пользователи
Сообщений: 198
Пол: Мужской

Репутация: -  1  +


Цитата(IUnknown @ 15.10.2011 15:24) *

Для твоего случая достаточно:
   i := 1;
   S2 := '';
   q := H;
   repeat
      case q of
         H:
         begin
            case S1[i] of
               '.':
               begin
                  q:=B;
                  S2:=S2+S1[i];
               end;
               '+', '-':
               begin
                  q:=A;
                  S2:=S2+S1[i];
               end;
               '0'..'9':
               begin
                  q:=C;
                  S2:=S2+S1[i];
               end;
               else q:=H;
            end; // case
            Inc(i); // Это делается всегда
         end;

         A, B:
         case S1[i] of
            '0'..'9':
            begin
               q:=Succ(Succ(q)); // Вместо case A => q := C и case B => q := D
               S2:=S2+S1[i];
               Inc(i);
            end;
            else
            begin
               q:=H;
               S2:='';
            end;
         end;
         C:
         case S1[i] of
            '.':
            begin
               q:=F;
               S2:=S2+S1[i];
               Inc(i);
            end;
            '0'..'9':
            begin
               q:=C;
               S2:=S2+S1[i];
               Inc(i);
            end;
            else q:=S;
         end;

         F, D: // Эти 2 ветки у тебя вообще идентичные
         case S1[i] of
            '0'..'9':
            begin
               q:=D;
               S2:=S2+S1[i];
               Inc(i);
            end;
            else q:=S;
         end;

      end;
   until q = S;
я просто чуть-чуть упростил твой же код, объединил одинаковые (и почти одинаковые, как в случае q=A и q=B) ветки...

действительно, а я даже не заметил
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
marwell
сообщение 16.10.2011 11:57
Сообщение #8


Бывалый
***

Группа: Пользователи
Сообщений: 198
Пол: Мужской

Репутация: -  1  +


еще забыл smile.gif
надо
...
until (q = S) or (i = Length(s1) + 1);
...

на случай если в строке вовсе нет чисел

Сообщение отредактировано: marwell - 16.10.2011 11:58
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

- Текстовая версия 22.07.2025 21:15
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"