Консультация онлайн # 161458

Раздел: Pascal / Delphi / Lazarus
Автор вопроса: Abelman
Дата: 26.02.2009, 11:29 Консультация неактивна
Поступило ответов: 1
Помогите, пожалуйста, с задачей!

Задачу нужно сделать с помощью указателей (создавать списки)и через процедуры. Также нужно использовать операторы case и ord.
Условие задачи
С клавиатуры вводится строка (тип string), в которой записан многочлен. Используя операторы case и ord нужно «распознать» многочлен, создать список и вывести многочлен на экран. Причем выведенный многочлен должен быть с упорядоченными степенями и коэффициентами
(пример)
Вводим
2x^3+4x^5+2+x^3
Выводим
4x^5 + 3x^3 + 2

Задачу нужно сделать с помощью указателей (создавать списки)и через процедуры.

Ответ # 1, Шевченко Дмитрий (Посетитель)

Здравствуйте, Abelman!

Код программы в приложении.
Сначала вводятся данные и записываются в список (каждый следующий элемент записывается на первое место (так проще)), до тех пор пока не введём 0 0.
Потом перебирается список и ищется член с максимальной степенью. Далее список перебирается ещё раз и у всех членов с этой степенью суммируется коэффициент, далее всё это выводится на экран.
Успехов! smile

С уважением, Дмитрий.

Приложение:


Шевченко Дмитрий

Посетитель
26.02.2009, 22:24
Нет оценки ответа

Мини-форум консультации # 161458

Шевченко Дмитрий

177994

= общий =    26.02.2009, 22:58
Несколько исправлений к программе:
константа N (const N = 100;{max кол-во вводимых пар}) не нужна - можете стереть, и строку
" list^.next:=list^.next^.next;{Удаляем первый элемент т.к. он нулевой}" тоже лучше стереть, т.к. при этом первый элемент не удаляется, а просто "забывается" что он есть и при очистке памяти от списка, он остаётся и занимает память. На работоспособность программы эти изменения никак не повлияют.
Если что-то непонятно - пишите.
неизвестный

178101

= общий =    27.02.2009, 20:17
Большое Вам спасибо, но программа должна работать по другому. Должны быть использованны операторы case и ord.

Например, мы ввели строку 144x^4+7x+5. А дальше, используя оператор case мы "распознаём" введённую строку.
Шевченко Дмитрий

178105

= общий =    27.02.2009, 21:03
виноват, извиняюсь smile
перепутал вопрос с похожим, в котором надо было вводить многочлен так как я сделал..
Сейчас переделаю и напишу так как Вам необходимо.
Правда не очень представляю зачем и где тут использовать ord, но постараюсь сделать с ним.
Шевченко Дмитрий

178132

= общий =    27.02.2009, 23:34
Вот исправленная версия:
Код
program z161458;
type Tkoef = Real;{тип коэффициентов (целые или вещественные)}
     TStep = Real;{тип степеней (целые или вещественные)}
    T4len = record{член последовательности - }
        koef : TKoef;{коэффициент перед ним}
        step : TStep;{и его степень}
    end;

    ptr = ^element;
    element = record
        data : T4len;
        next : ptr;
    end;
var list : ptr;

{--------------------------------------------------------}
procedure Initialize;
begin
  new(list);
  list^.next := nil;
end;
procedure Die;
  var elem:ptr;
begin
  elem:=list;
  While list <> nil do
  begin
    list:=list^.next;
    dispose(elem);
    elem:=list;
  end;
end;
{--------------------------------------------------------}
procedure AddFirst(elem : ptr);{добавление элемента в начало списка}
begin
  if list^.next = nil then{если список пуст - }
    list^.next := elem{прописываем добавляемый элемент в качестве первого}
  else{иначе}
  begin
    elem^.next := list^.next;{назначаем "хвосту"(ссылке на следующий элемент) текущего элемента первый элемент списка}
    list^.next := elem;{прописываем добавляемый элемент в качестве первого}
  end;
end;

procedure Add4len(s:String);{разбор одного члена (строки вида "-23x^3")}
  var elem:ptr;
    koef,step:String;
    code:Integer;
begin
  new(elem);
  IF pos('x',s) > 0 then{Если степень не нулевая}
  begin
    koef:=copy(s,1,pos('x',s)-1);{запоминаем коэффициент}
    IF (koef = '+')or(koef = '-') then{если член вида "-x.." или "+x.." то коэффициент соответственно равен 1 или -1}
      koef:=koef + '1';

    IF pos('^',s) > 0 then{Если степень не равна 1}
      step:=copy(s,pos('^',s)+1,255){запоминаем её}
    Else
      step:='1';
  end
  Else{если степень равна нулю}
  begin
    koef:=s;{то весь член - это коэффициент}
    Step:='0';
  end;
  {добавляем член в список}
  val(koef,elem^.data.koef,code);
  val(step,elem^.data.step,code);
  elem^.next := nil;
  AddFirst(elem);
end;
procedure vvod;{ввод данных}
  var s,s4len:string;
    i:Integer;
    isStepen:boolean;
    znak:char;
begin
  WriteLn('Введите многочлен: ');
  ReadLn(s);
  While pos(' ',s) > 0 do{удаляем пробелы из строки}
    delete(s,pos(' ',s),1);
  s4len:='';
  isStepen:=false;
  znak:='+';
  For i:= 1 to length(s) do{перебираем строку}
    case ord(s[i]) of{если символ: }
      43,45:{+ или -}
        IF isStepen then{если это знак степени (например, в строке "2x^-3" "-" перед "3")}
        begin
          s4len:= s4len + s[i];{просто дописываем знак к члену последовательности}
          isStepen:=false;
        end
        Else{если это не знак степени - }
        begin
          Add4len(znak+s4len);{добавляем член в список}
          s4len:='';
          znak:=s[i];{запоминаем знак перед следующим членом}
        end;
      94: begin{^ - знак степени}
        s4len:= s4len + s[i];
        isStepen:=true;
      end;
      Else begin{иначе}
        s4len:= s4len + s[i];{дописываем символ к члену}
        isStepen:=false;{знак степени уже учли}
      end;
    end;
  IF length(s4len) > 0 then{добавляем последний член}
    Add4len(znak+s4len);
end;

Function FMax(var max:TStep):boolean;{поиск максимальной оставшейся степени с коэффициентом <> 0}
  var nashli:boolean;
  el:ptr;
  i:Integer;
begin
  nashli:=false;
  el := list^.next;
  i := 1;
  while el <> nil do
  begin
    IF ((el^.data.step > max) or (not nashli)) and (el^.data.koef <> 0) then
    begin
      max:=el^.data.step;
      nashli:=true;{в списке ещё есть члены последовательности, с ненулевым коэффициентом}
    end;
    inc(i);
    el := el^.next;
  end;
  FMax:=nashli;
end;

var
  el:ptr;
  kol,i:Integer;
  max:TStep;
  koef:TKoef;
  StrKoef,StrStep:String[20];
begin
  Initialize;
  vvod;
  While FMax(max) do{пока в списке есть члены с ненулевыми коэффициентами}
  begin
    koef:=0;
    {считаем коэффициент перед членом с максимальной степенью в списке}
    el := list^.next;
    i := 1;
    while el <> nil do
    begin
      IF el^.data.step = max then{если это член с максимальной степенью - }
      begin
        koef:=koef + el^.data.koef;{считаем суммарный коэффициент перед ним}
        el^.data.koef := 0;{зануляем коэффициент, чтобы больше не считать этот член}
      end;
      inc(i);
      el := el^.next;
    end;

    Str(max:0:3,StrStep);{если степени - целые числа, то ":0:3" не нужно}
    Str(koef:0:3,StrKoef);{если коэффициенты - целые числа, то ":0:3" не нужно}
    IF Strkoef[1] <> '-' then
      StrKoef:= '+' + StrKoef;
    IF koef <> 0 then{выводим приведённый член последовательности}
      IF max = 0 then
        Write(StrKoef + ' ')
      Else
        IF max = 1 then
          Write(StrKoef + 'x ')
        Else
          Write(StrKoef+'x^'+StrStep+' ');
  end;
  die;
  ReadLn;
end.

Изменился только ввод многочлена и исправил недочёты, про которые писал выше.

Ещё раз извиняюсь за невнимательно прочтённое задание.
неизвестный

178221

= общий =    28.02.2009, 19:07
Большое вам спасибо!
Возможность оставлять сообщения в мини-форумах консультаций доступна только после входа в систему.
Воспользуйтесь кнопкой входа вверху страницы, если Вы зарегистрированы или пройдите простую процедуру регистрации на Портале.