Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Многочлены


Denis__ ©   (2008-12-18 17:32:00) 

Вопрос не про Делфи, а про алгоритм. Задача - ввести во внутреннее представление многочлен, который вводится как строка - алгебраическая сумма слагаемых вида ax^k, ax, x^k, x, a. Где a, k - целые,>=1. Представление - однонаправленный список, но это не важно. Важно разделить многочлен на одночлены и потом их на коэффициент "а" и степень "k". Сделал, все работает, но сомневаюсь в правильности подхода. Кто чем может:)


procedure ParseMon(s : String; var a, k : Integer);
var
  i, e : Integer;
  r : Real;
begin
    i := Pos('x', s);
    if i = 0 then
       s := s + 'x^0';
    i := Pos('x', s);
    if i = 1 then
    begin
       s := '1' + s;
       i := 2;
    end;
    if i = Length(s) then
       s := s + '^1';
    (**********************************************************************)
    {PARSE}
    i := 1;
    while s[i] <> 'x' do
          i := i + 1;
    Val(Copy(s, 1, i - 1), r, e);
    a := trunc(r);
    Delete(s, 1, i + 1);
    Val(s, r, e);
    k := trunc(r);
end;

//Это основное!!!
procedure InputPolynom(var p : TLink);
var
  s, Mon : String;
  i, a, k : Integer;
  next_ : Boolean;
begin
    Write('Input polynom:');
    Readln(s);

    CheckRubbish(s);

    if s[1] = '-' then
    begin
         Delete(s, 1, 1);
         next_ := True;
    end
    else
        next_ := False;

    while s <> '' do
    begin
         i := 1;
         while not (s[i] in ['+', '-']) do
               i := i + 1;
         Mon := Copy(s, 1, i - 1); {Monopolian}

         ParseMon(Mon, a, k);

         if next_ then a := -a;
         next_ := s[i] = '-';

         AddToList(p, a, k);

         Delete(s, 1, i);
    end;
end;


Denis__   (2008-12-19 16:27:00) [1]

Разобрался. Немного исправил. Не всегда  корректно работало

procedure parse1(s : String; var a1,k1 : Integer);
var
  a, k : real;
  offs, e : Integer;
begin
 offs:= 1;
 if( s[1] = 'x' )then
     a:= 1
 else
     val(s, a, offs); //Помещает в а 0.0, если в строке есть х (*)
 k:= 0;
 if(offs > 0)then
 begin
      if s[1] <> 'x' then
         val(Copy(s, 1, offs - 1), a, e);{пока не нашел, как иначе            исправить (*)}

      if(s[offs] <> 'x')then
        Error('invalid format');
      if (Length( s ) > offs )then
        begin
             if((s[offs+1] <> '^') or (Length( s ) < offs+2))then
               Error('invalid format');
             Delete(s, 1, offs+ 1);
             val(s, k, offs);
             if(offs <> 0)then
               Error('invalid format');
        end
        else
            k := 1.0;
 end;
 a1 := trunc(a);
 k1 := trunc(k);
end;


Denis__   (2008-12-19 15:42:00) [2]

Сейчас разберу, спасибо.


> - канонически - в линейной алгебре - таки используют просто
> вектор ak, k = 0..N

не очень понял, к чему это. Может поясните? )


han_malign   (2008-12-19 14:49:00) [3]


> Дополнять одночлены до вида ax^k? или можно было сделать проще?

offs:= 1;
if( s[1] = 'x' )then a:= 1
else
    val(s, a, offs);//декодирует значение и указывает на первый "неправильный" символ
k:= 0
if(offs > 0)then begin//существет литера не относящаяся к цифрам коэффициента
    if(s[offs] <> 'x')then//но она(литера) должна быть 'x'
        exit{invalid format};
    if( Length( s ) > offs )then begin//есть символы помимо 'x'
       //должны быть '^' и как минимум одна цифра
       if((s[offs+1] <> '^') or (Length( s ) < offs+2{ ^d}))then
           exit{invalid format};
       Delete(s, 1, offs+2);
       val(s, k, offs);
       if(offs <> 0)then//степень не является числом
           exit{invalid format};
    end;
end;


> И еще, возможно, есть какие-нибудь замечания по коду?

- канонически - в линейной алгебре - таки используют просто вектор ak, k = 0..N


Denis__   (2008-12-19 13:50:00) [4]

Да, именно так. Потом выполняются различные действия с многочленами - их сложение, перемножение, нахождение целых корней, вычисление производной по переменной х, и т.д. Структура, в которой хранится многочлен выглядит так

type
  TLink = ^TElem;
  TElem = record
        a, k : Integer; //т.е. а и k надо выделять в любом одночлене
        next : TLink;
  end;  


Мой вопрос - целесообразно ли действовать так, как это делал я? Дополнять одночлены до вида ax^k? или можно было сделать проще?
И еще, возможно, есть какие-нибудь замечания по коду?


Jeer   (2008-12-19 09:41:00) [5]

Надо понимать так, что a и k - произвольные целые числа и нужно любой из вариантов записи одночлена ( a, x, x^k, ax ) привести к виду ax^k, причем при отсутствии a или k они должны быть введены как '1', а при отсутствии x строка расширяется на 'x^0' ?


Denis__   (2008-12-18 18:31:00) [6]

Ну вот это
begin
   i := Pos('x', s);
   if i = 0 then
      s := s + 'x^0';
   i := Pos('x', s);
   if i = 1 then
   begin
      s := '1' + s;
      i := 2;
   end;
   if i = Length(s) then
      s := s + '^1';


Это добавление до вида ax^k каждого одночлена. Может надо было как-нибудь иначе действовать? Проще, возможно?


Jeer   (2008-12-18 18:27:00) [7]

Если работает, то подход правильный был, значит.
Может не устраивать по иным критериям, но их надо озвучить.


Наверх

Титульная страница Поиск, карта сайта Написать письмо