Форум «Всё о Паскале» _ Задачи _ Бинарное дерево (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.
И ещё: при пошаговом выполнении в случае для описанной формулы со скобками выкидывает на рабочий стол.
А происходит это по тривиальной причине: попытка обращения по нулевому указателю здесь -
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, а ты заставляешь систему переходить по нулевому указателю... Читай ответы внимательнее...
Ладно. Давайте вернёмся к начальному сообщению. как мне
Цитата
подкорректировать текст программы
- на ум приходит только эта бредовая "защита". Уже вторые сутки пробую и никак... Что мне здесь нужно сделать?