Помощь - Поиск - Пользователи - Календарь
Полная версия: "нормальный" вывод выражений
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
marwell
смысл в следующем: пользователем вводятся количество уравнений с тремя неизвестными x,y,z и коэффициенты.
надо добиться от программы "нормального" вывода выражений, т.е. например вместо 0*x+1*y+-2*z=2 вывело y-2z=2.
вот мой последний (наверное, не лучший, но какой смог) вариант:
function Rus(mes: string):string;
var i: integer;
begin
for i:=1 to length(mes) do
case mes [i] of
'А'..'п': mes[i]:=chr(Ord (mes [i])-64);
'р'..'я': mes[i]:=chr(ord (mes[i])-16);
end;
rus:=mes;
end;

procedure vivod(a:real; j:integer; f:boolean);
begin
case j of
1: if a<>0 then begin
if a>0 then begin
if a=1 then write('x')
else write(a:5:2,'x'); end
else begin
if a=-1 then write('-x')
else write(a:5:2,'x'); end;
f:=false;
end
else f:=true;
2: if a<>0 then begin
if f=true then begin
if a>0 then begin
if a=1 then write('y')
else write(a:5:2,'y'); end
else if a=-1 then write('-y')
else write(a:5:2,'y'); end
else if a>0 then begin
if a=1 then write('+y')
else write('+',a:5:2,'y'); end
else if a=-1 then write('-y')
else write(a:5:2,'y');
f:=false;
end
else f:=true;
3: if a<>0 then begin
if f=true then begin
if a>0 then begin
if a=1 then write('z')
else write(a:5:2,'z'); end
else if a=-1 then write('-z')
else write(a:5:2,'z'); end
else if a>0 then begin
if a=1 then write('+z')
else write('+',a:5:2,'z'); end
else if a=-1 then write('-z')
else write(a:5:2,'z');
f:=false;
end
else f:=true;
4: write(a:5:2);
end;
end;

var n,i,j:integer;
m: array [1..100,1..4] of real;
f: boolean;
begin
writeln('a1x+b1y+c1z = d1');
writeln('a2x+b2y+c2z = d2');
writeln('...');
writeln('_________________');
writeln(rus('Введите количество уравнений: '));
readln(n);
for i:=1 to n do begin
j:=1;
while j<=4 do begin
write(rus('Введите а'),i,' = ');
readln(m[i,j]);
Inc(j);
write(rus('Введите b'),i,' = ');
readln(m[i,j]);
Inc(j);
write(rus('Введите с'),i,' = ');
readln(m[i,j]);
Inc(j);
write(rus('Введите d'),i,' = ');
readln(m[i,j]);
Inc(j);
end;
end;
write(rus('Нажмите Enter для вывода уравнений-->'));
readln;
for i:=1 to n do begin
j:=1;
f:=false;
while j<=4 do begin
vivod(m[i,j],j,f);
inc(j);
vivod(m[i,j],j,f);
inc(j);
vivod(m[i,j],j,f);
write('=');
inc(j);
vivod(m[i,j],j,f);
inc(j);
writeln;
end;
end;
readln;
end.

вроде бы дает желаемый результат, но только при первом коэффициенте при x, равном 0, выводит "+y+z=1". Не могу убрать этот знак плюс. Второй день разбираю, но не могу разобраться
volvo
Я б вообще переписал всю процедуру вывода - там сплошной копипаст, "это не наш метод". Смотри, насколько все проще:

const size = 4;
type
Coeffs = array [1 .. size] of Real;

procedure Print(arr : Coeffs);
const
Letters : array[1 .. size] of string[1] =
('x', 'y', 'z', '');
Sign : array[boolean, boolean] of Char =
(('+', '-'), (' ', '-'));
eps = 0.000001;

var
i : integer;
begin
for i := 1 to size do
begin
{ Перед тем, как напечатать свободный член, в любом случае надо "=" }
if i = size then write('=');

{ Теперь проверяем коэффициенты }

{ Равен 0? Прекрасно. Не выводим ничего. За исключением одного случая... }
if abs(arr[i]) < eps then
begin
{ ... вот этого: Если это свободный член - надо его вывести, иначе некрасиво будет }
if i = size then write(arr[i]:4 :2);
end
else
{ Ага. Не ноль... Единица? }
if abs(abs(arr[i]) - 1) < eps then
{ Единица. Если печатается первый или свободный коэфф., то плюса не надо,
именно для этого я описал Sign как двумерный массив. Если первый индекс
равен False, то плюс напечатается, если True - то не напечатается... }
write(Sign[(i = 1) or (i = size), arr[i] < 0], Letters[i])

{ Не ноль и не 1. Прекрасно. Просто печатаем знак и значение. Опять же,
знак "+" выводим только НЕ у первого и НЕ у свободного коэфф-та. }
else write(Sign[(i = 1) or (i = size), arr[i] < 0],
Abs(arr[i]):4 :2, Letters[i]);
end;
end;

{ M теперь описывается вот так: }
Var M : array[1 .. 100] of Coeffs;

{ А вывод уравнений - вот такой: }
{ ... }
for i := 1 to n do
begin
Print(M[ i ]);
end;
{ ... }

Проще, правда?
marwell
Цитата(volvo @ 27.02.2011 15:46) *

Я б вообще переписал всю процедуру вывода - там сплошной копипаст, "это не наш метод". Смотри, насколько все проще:

const size = 4;
type
Coeffs = array [1 .. size] of Real;

procedure Print(arr : Coeffs);
const
Letters : array[1 .. size] of string[1] =
('x', 'y', 'z', '');
Sign : array[boolean, boolean] of Char =
(('+', '-'), (' ', '-'));
eps = 0.000001;

var
i : integer;
begin
for i := 1 to size do
begin
{ Перед тем, как напечатать свободный член, в любом случае надо "=" }
if i = size then write('=');

{ Теперь проверяем коэффициенты }

{ Равен 0? Прекрасно. Не выводим ничего. За исключением одного случая... }
if abs(arr[i]) < eps then
begin
{ ... вот этого: Если это свободный член - надо его вывести, иначе некрасиво будет }
if i = size then write(arr[i]:4 :2);
end
else
{ Ага. Не ноль... Единица? }
if abs(abs(arr[i]) - 1) < eps then
{ Единица. Если печатается первый или свободный коэфф., то плюса не надо,
именно для этого я описал Sign как двумерный массив. Если первый индекс
равен False, то плюс напечатается, если True - то не напечатается... }
write(Sign[(i = 1) or (i = size), arr[i] < 0], Letters[i])

{ Не ноль и не 1. Прекрасно. Просто печатаем знак и значение. Опять же,
знак "+" выводим только НЕ у первого и НЕ у свободного коэфф-та. }
else write(Sign[(i = 1) or (i = size), arr[i] < 0],
Abs(arr[i]):4 :2, Letters[i]);
end;
end;

{ M теперь описывается вот так: }
Var M : array[1 .. 100] of Coeffs;

{ А вывод уравнений - вот такой: }
{ ... }
for i := 1 to n do
begin
Print(M[ i ]);
end;
{ ... }

Проще, правда?

намного! спасибо большое, буду разбираться

Добавлено через 19 мин.
только один вопрос: а как теперь будет ввод этих коэффициентов? просто цикл с Readln[ M[ i ] ] ведь не пойдет
marwell
for i := 1 to n do
begin
write(rus('Введите а'),i,' = ');
readln(coeffs[1]);
write(rus('Введите b'),i,' = ');
readln(coeffs[2]);
write(rus('Введите с'),i,' = ');
readln(coeffs[3]);
write(rus('Введите d'),i,' = ');
readln(coeffs[4]);
readln;
Print(M[ i ]);
writeln;
end;

а в чем ошибка такого ввода коэффициентов?

Добавлено через 1 мин.
аа, кажется и сам понял
volvo
Цитата
просто цикл с Readln[ M[ i ] ] ведь не пойдет
Угу. Зато с
ReadLn(M[i][1]); { и так далее } 

пойдет. Но лучше бы это тоже вынести в отдельную процедуру:
procedure GetCoeffs(var arr: Coeffs);
var i : integer;
begin
for i := 1 to size do
begin
write(rus('Введите ' + Chr(Ord('a') + i - 1)), ' = ');
readln(arr[i]);
end;
end;

{ и вводить так: }
for i := 1 to n do
GetCoeffs(M[ i ]);
{ ... }

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