Помощь - Поиск - Пользователи - Календарь
Полная версия: Поиск числа в строке
Форум «Всё о Паскале» > Delphi, Assembler и другие языки. > Delphi
marwell
Добрый вечер
Собственно, само задание: вводится строка, найти в этой строке первое число (может быть с запятой) (учитываются и знаки '+-') в общем из строки типа +-+--+-+-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;
IUnknown
Открываешь книгу Р. Хантера "Проектирование и конструирование компиляторов" на стр. 45-46, и смотришь, как строится конечный автомат, распознающий в строке вещественное число. Небольшая доработка - и получаешь функцию, которая вернет тебе первое вхождение вещественного числа в строке.
marwell
Цитата(IUnknown @ 14.10.2011 12:12) *

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

спасибо, попробую
а так задачу решил, код вышел длинный и некрасивый, но работающий
marwell
О_о почему то мое сообщение отправилось два раза
marwell
вот что получилось с использованием конечного автомата

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
IUnknown
Для твоего случая достаточно:
   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) ветки...
marwell
Цитата(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) ветки...

действительно, а я даже не заметил
marwell
еще забыл smile.gif
надо
...
until (q = S) or (i = Length(s1) + 1);
...

на случай если в строке вовсе нет чисел
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.