Добрый вечер Собственно, само задание: вводится строка, найти в этой строке первое число (может быть с запятой) (учитываются и знаки '+-') в общем из строки типа +-+--+-+-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
14.10.2011 12:12
Открываешь книгу Р. Хантера "Проектирование и конструирование компиляторов" на стр. 45-46, и смотришь, как строится конечный автомат, распознающий в строке вещественное число. Небольшая доработка - и получаешь функцию, которая вернет тебе первое вхождение вещественного числа в строке.
marwell
14.10.2011 14:04
Цитата(IUnknown @ 14.10.2011 12:12)
Открываешь книгу Р. Хантера "Проектирование и конструирование компиляторов" на стр. 45-46, и смотришь, как строится конечный автомат, распознающий в строке вещественное число. Небольшая доработка - и получаешь функцию, которая вернет тебе первое вхождение вещественного числа в строке.
спасибо, попробую а так задачу решил, код вышел длинный и некрасивый, но работающий
marwell
14.10.2011 14:04
О_о почему то мое сообщение отправилось два раза
marwell
15.10.2011 12:02
вот что получилось с использованием конечного автомата
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;
разница, мягко говоря, огромная
Добавлено через 1 мин. IUnknown, спасибо за совет
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
15.10.2011 19:55
Цитата(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
16.10.2011 11:57
еще забыл надо
... until (q = S) or (i = Length(s1) + 1); ...
на случай если в строке вовсе нет чисел
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.