Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ Раскрыть с кобки в выражениии

Автор: -Антон- 29.11.2007 21:04



for g:=1 to 26 do
Begin
If pos(')',s)=(pos('(',s)-1) then
Begin

s9:=copy(s,1,pos(')',s)-1);
s8:=copy(s,pos(')',s)+1,length(s)-pos('(',s)+1);
s10:=s8;
delete(s,1,Length(s8)+length(s9)+1);

for ch5 := 'A' to 'Z' do
begin
if pos(ch5, s9) > 0 then
prs1 := prs1 + ch5;
end;
s9:=prs1;
writeln(s9);
For m:=1 to (length(s9)-1) do
Begin
S8:=s8+'+'+s8;
End;
Insert(s9[1],s8,1);
For m:=1 to (length(s9)-1) do
Begin
Insert(s9[1+m],s8,pos(s9[1],s8)+length(s10)+2);
End;
s:=s+s8;



End;
If pos(per[g],s)=(pos('(',s)-1) then
begin
If pos('+',s)>pos('(',s) then
if pos('+',s)<pos(')',s) then {A*(A+B) }
begin
insert(per[g],s,pos('+',s)+1);
delete(s,pos('(',s)+length(s),1);
{ delete(s,pos('(',s),1);
delete(s,pos(')',s),1); }

End;
If pos(per[g],s)=(pos('(',s)-1) then {A*(A*B)}
begin
delete(s,pos('(',s),1);
delete(s,pos('(',s)+length(s),1);
End;
End;
End;
Writeln(s);


Мне надо раскрыть скобки в выражении, я вошел в тупик в таком случае, когда (A+C)(A+B) , в первом цткле я такое выражение преобразую в A(A+B)+C(A+B), во втором цикле должно выйти AA+AB+CA+CB, а выходит AA+AB+CA+B, не подскажете в чем ошибка или есть какой-нибудь другой способ.






Автор: Malice 30.11.2007 3:20

Ошибка в том, что pos всегда ищет с начала строки, а ты похоже думаешь что как то иначе..
По всему коду прогядувается такая логика, например:

  If pos(')',s)=(pos('(',s)-1) then

Хочешь этим найти ")(" ? Для твоего же выражения с двумя скобками не выйдет..
И далее похоже. А вообще - здесь однозначно панет рекурсией. Вдруг выражение с вложенными скобками или умножение стоит по разные стороны от скобок, все варианты не переберешь.

Автор: Гость 1.12.2007 1:00

Рекурсией? Это например как, на ловах хотя бы...? Тоесть мне вообще надо это все дело подругому делать?

Автор: Malice 1.12.2007 13:50

Цитата(Гость @ 30.11.2007 21:00) *

Рекурсией? Это например как, на словах хотя бы...? Тоесть мне вообще надо это все дело подругому делать?

Ну это мне так кажется, ведь будет гараздо проще.. Нужно будет научить прогу базовым операциям, типа - раскрытие скобки при умножении слева, при умножении справа, умножение скобок между собой например..

Вот примерчик небольшой с принципом:
uses crt;
function upr (s:string):string;
var i,n,k:integer;
ss,s1,s2:string;
c:char;
begin
if pos ('(',s)=0 then begin upr:=s; exit; end;
I:=1; n:=pos('(',s)+1; k:=0;
repeat
if s[n]='(' then begin inc (i); inc (k); end;
if s[n]=')' then dec (i);
inc (n);
until i=0;

if k>0 then begin {есть вложеннные скобки, надо начинать с них}
s:=upr(copy(s,1,pos('(',s))+
upr(copy(s,pos('(',s)+1,n-pos('(',s)-2))+
copy (s,n-1,255));
end;

{if (s[pos('(',s)-1] in ['A'..'Z']) and умножение справа, аналогично делается
(s[pos(')',s)+1] in ['A'..'Z']) then
}

{ умножение скобок
}

if (s[pos('(',s)-1] in ['A'..'Z']) and
not(s[pos(')',s)+1] in ['A'..'Z']) then begin {умножение слева}
i:=pos('(',s)-1;
s1:='';
while (s[i] in ['A'..'Z']) and (i>0) do begin s1:=s[i]+s1; dec (i); end;
ss:=copy(s,1,i);
i:=pos('(',s)+1;
repeat
s2:='';
while (s[i] in ['A'..'Z']) and (i<length(s)) do begin s2:=s2+s[i]; inc (i); end;
ss:=ss+s1+s2;
if s[i]<>')' then
while not(s[i] in (['A'..'Z'])) and (i<length(s)) do begin ss:=ss+s[i]; inc (i); end;
until s[i]=')';
ss:=ss+copy (s,i+1,255); s:=ss;
end;

upr:=upr(s); {строка на всякий случай, ведь может быть несколько простых операций раскрытия
а мы раскрываем только первую}
end;


begin
writeln(upr('D(A(A+B)+B(C+B))+C(E+F)'));
end.

Конечно это только пример.
Умножение скобок типа (a+b)(b+c)(d+a) тоже не обязательно сильно наворачивать достаточно уметь раскрывать 2 скобки. Т.е. нашел что они умножаются (a+b)(b+c)(d+a), выделенный фрагмент передал в на упрощение, окружил скобками и приклеил опять обратно. Вышло (ab+ac+bb+bc)(d+a) и по кругу..