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

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

Форум «Всё о Паскале» _ Задачи _ Бинарное дерево (pascal 7.1)

Автор: Dmitry 31.05.2006 2:33

Добрый день.
В файле записана формула, например (5*(3+8)) . (Формула может состоять и из одного числа. Тогда в скобки она не берётся). Файл записан в папке D:\Work. Необходимо представить её в виде двоичного
дерева----------*-------------------
-----------------/----\-----------------
---------------5------+----------------
---------------------/--\--------------
-------------------3-----8-------------
и вычислить (с помощью рекурсии) значение полученного дерева-формулы.
(5*(3+8)) будет равно 55. Я попытался создать программу для решения этой проблемы, для формулы, состоящей из одного числа она работает, а вот для описанного выше выражения выдаёт неправильный результат. И ещё: при пошаговом выполнении в случае для описанной формулы со скобками выкидывает на рабочий стол. Помогите подкорректировать текст программы.(код программы прилагается)

Код
program Proga;
const
  Chisla: set of Char = ['0', '1','2','3','4','5','6','7','8','9'];
  Znaki: set of Char = ['+','-','*'];
type
bt = string;
  Adr = ^Derevo;
  Derevo = record
             L: Adr;
             R: Adr;
             Inf: Integer;
           end;
var
  TextFile: Text;
  Der1, Der2: Adr;
  Dat: bt;
  N: Integer;
  A1: Integer;
function Pered(TT: Adr; var  N: Integer): Adr;  {строим дерево}
var
  C: Char;
  D, X: Integer;
const
  A: bt = '';
begin
if N <= Length(Dat) then
begin
  A := '';
  Inc(N);
  C := Dat[N];
  if C in Chisla then
  begin
    D := N;
    while (Dat[D] in Chisla) and (D <= Length(Dat)) do
    begin
      A := A + Dat[D];
      Inc(D);
    end;
    if D - 1 = N then
      A := Dat[N];
    Val(A, A1, X);
    N := D;
    TT^.L := nil;
    TT^.R := nil;
    TT^.Inf := A1;
  end
  else
  begin
    TT^.L := Pered(TT^.L, N);
    if Dat[N] = '-' then
      TT^.Inf := -1
    else
    if Dat[N] = '+' then
      TT^.Inf := -2
    else
    if Dat[N] = '*' then
      TT^.Inf := -3;
    TT^.R := Pered(TT^.R, N);
  end;
end;
end;
function Rezult(Tree: Adr): Integer; {считаем значение дерева}
var
  B: Integer;
begin
  if Tree^.L = nil then
    Rezult := Tree^.Inf
  else
  begin
    case Tree^.Inf of
      -1: Rezult := Rezult(Tree^.L) - Rezult(Tree^.R);
      -2: Rezult := Rezult(Tree^.L) + Rezult(Tree^.R);
      -3: Rezult := Rezult(Tree^.L) * Rezult(Tree^.R);
    end;
  end;
end;
begin
  Assign(TextFile, 'D:\Work\TextFile.txt');
  Reset(TextFile);
  New(Der1);
  New(Der2);
  Der1 := nil;
  Der2 := Der1;
  Readln(TextFile, Dat);
  N := 0;
  Pered(Der1, N);
  Writeln(Rezult(Der1));
end.



Прикрепленные файлы
Прикрепленный файл  GGGG.PAS ( 1.65 килобайт ) Кол-во скачиваний: 278

Автор: volvo 31.05.2006 3:08

Цитата
И ещё: при пошаговом выполнении в случае для описанной формулы со скобками выкидывает на рабочий стол.
А происходит это по тривиальной причине: попытка обращения по нулевому указателю здесь -
    TT^.L := Pered(TT^.L, N);
, однако TT пока равно nil... Все, ошибка... Программа вылетела...

Так что и результату никакой веры быть не может...

Автор: volvo 31.05.2006 3:20

Кстати, может тебя вот это заинтересует:
http://forum.pascal.net.ru/index.php?s=&showtopic=7346&view=findpost&p=52604
?

(там тоже происходило вычисление выражения с помощью дерева)

Автор: Dmitry 31.05.2006 3:38

Цитата(volvo @ 30.05.2006 23:08) *

А происходит это по тривиальной причине: попытка обращения по нулевому указателю здесь -
    TT^.L := Pered(TT^.L, N);
, однако TT пока равно nil... Все, ошибка... Программа вылетела...

Так что и результату никакой веры быть не может...

Хорошо, предположим, что так, но, скажите, когда я делаю такую защиту:
  if TT^.L <> nil then
begin
TT^.L := Pered(TT^.L, N);
if Dat[N] = '-' then
TT^.Inf := -1
else
if Dat[N] = '+' then
TT^.Inf := -2
else
if Dat[N] = '*' then
TT^.Inf := -3;
TT^.R := Pered(TT^.R, N);
end;

, то почему ничего не изменяется, т.е. результат по-прежнему неправильный. И ещё: вылетает на вот этом месте
 TT^.Inf := A1;

Автор: volvo 31.05.2006 3:44

Цитата
Хорошо, предположим, что так
Понимаешь, в чем дело? Я не предполагаю, а говорю то, о чем мне сказал FPC (который прекрасно ловит вот такие вещи)

Цитата
когда я делаю такую защиту:
Это не защита, а бред. Я же говорю, у тебя TT = nil, а ты заставляешь систему переходить по нулевому указателю... Читай ответы внимательнее...

Автор: Dmitry 31.05.2006 3:48

Цитата(volvo @ 30.05.2006 23:44) *

Понимаешь, в чем дело? Я не предполагаю, а говорю то, о чем мне сказал FPC (который прекрасно ловит вот такие вещи)

Это не защита, а бред. Я же говорю, у тебя TT = nil, а ты заставляешь систему переходить по нулевому указателю... Читай ответы внимательнее...

Ладно. Давайте вернёмся к начальному сообщению. как мне
Цитата
подкорректировать текст программы
- на ум приходит только эта бредовая "защита". Уже вторые сутки пробую и никак... Что мне здесь нужно сделать?