imho.ws
IMHO.WS  

Вернуться   IMHO.WS > Компьютеры > Программирование
Опции темы
Старый 23.10.2005, 12:48     # 1
Sam Dark
Member
 
Аватар для Sam Dark
 
Регистрация: 03.07.2003
Адрес: Voronezh, Russia
Пол: Male
Сообщения: 294

Sam Dark МолодецSam Dark МолодецSam Dark Молодец
Польская запись и дерево арифметического выражения

Нужно решить вот такую задачку:
Цитата:
Построить дерево арифметического выражения, нарисовать дерево и посчитать выражене.

Вид дерева для (A+B)*(C+D)-E:
Код:
                           -
                          / \
                         /   \
                        *     E
                       / \
                      /   \
                     /     \
                    /       \
                   +         +
                  / \       / \
                 /   \     /   \
                A     B   C     D
Забрёл сюда:
http://algolist.manual.ru/syntax/revpn.php

Решил строить дерево из польской записи. (Запись получил. Delphi.)
Как реализовать?

Спасибо.
__________________
Это жжжж неспроста...
Sam Dark вне форума  
Старый 23.10.2005, 15:02     # 2
Trotil
Advanced Member
 
Аватар для Trotil
 
Регистрация: 21.04.2005
Адрес: град Москва
Сообщения: 431

Trotil Имеются все основания чтобы гордиться собойTrotil Имеются все основания чтобы гордиться собойTrotil Имеются все основания чтобы гордиться собойTrotil Имеются все основания чтобы гордиться собойTrotil Имеются все основания чтобы гордиться собойTrotil Имеются все основания чтобы гордиться собойTrotil Имеются все основания чтобы гордиться собойTrotil Имеются все основания чтобы гордиться собойTrotil Имеются все основания чтобы гордиться собой
А дерево нужно строить в текстовом режиме или можно графическими библиотеками?
В любом случае,можно написать некоторую рекурсивную процедуру (пример для графичекого отображения), основные шаги которой таковы:
x,y - координаты дерева
N - номер просматриваемого символа - перменная должна быть глобальной или введена в выражении польской записи спец символом или иметь там фиксированное место, пусть это будет первый символ - вариантов масса на самом деле

char * tree(char* str, int x, int у)
{
1)Отрисовываем знак текущей операции (N-тый символ в выражении) в точке (x,y)
2) Отрисовываем две ветви, определяем координаты концов ветвей
3) просматриваем (N--) символ:
если это "знак операции", то tree(str, текущее X, текущее Y, текущее N)
иначе отрисовываем этот символ
4) просматриваем (N--) символ:
если это "знак операции", то tree(str, текущее X, текущее Y, текущее N)
иначе отрисовываем этот символ
}

Минусы подхода: невозожно при таком подходе сделать красивое, ровное дерево - при одном дереве оно будет слишком растянуто, в другом случае - одни ветви будут наезжать на другие... Проблема лечится разбиением задачи на два этапа: на первом мы определяем характеристики дерева (например число уровней дерева), возможно, формируем некоторую новую структуру, где записываем все те данные для корректного отображения дерева (структуру формируем таким образом, что просматривая ее последовательно, не производя доп. вычислений, сразу отобразить нужное дерево); на втором этапе - отрисовка дерева с учетом информации, которую мы получили на первом этапе.

Последний раз редактировалось Trotil; 23.10.2005 в 15:23.
Trotil вне форума  
Старый 23.10.2005, 18:00     # 3
Trotil
Advanced Member
 
Аватар для Trotil
 
Регистрация: 21.04.2005
Адрес: град Москва
Сообщения: 431

Trotil Имеются все основания чтобы гордиться собойTrotil Имеются все основания чтобы гордиться собойTrotil Имеются все основания чтобы гордиться собойTrotil Имеются все основания чтобы гордиться собойTrotil Имеются все основания чтобы гордиться собойTrotil Имеются все основания чтобы гордиться собойTrotil Имеются все основания чтобы гордиться собойTrotil Имеются все основания чтобы гордиться собойTrotil Имеются все основания чтобы гордиться собой
Решил подкрепить свою идею надлядным примером работы алгоритма.
Возьмем, например, такое выражение: "CD*E+AB+*FG*-#" (решетка - символ-указатель на просматриваемый элемент)

1) Вход в функцию: рисуем "-" и ветви:
Код:
                            -
                           / \
                          /   \
                         /     \
                        /       \
2) Сдвигаем указатель "#" и обнаруживаем на месте первого аргумента "знак операции" "*". Запускаем ту же функцию, но уже строкой: "CD*E+AB+*FG*#-".
3) Отрисовываем "*" и ветви:
Код:
                            -
                           / \
                          /   \
                         /     \
                        /       \
                                 *      
                                 / \
                                /   \
Отрисовываем аргументы F,G. Знаков операции не обнаружено, поэтому новая функция не запускается, данная функция завершает работу и передается управление самой первой функции. Дерево имеет вид:
Код:
                            -
                           / \
                          /   \
                         /     \
                        /       \
                                 *      
                                 / \
                                /   \
                               F     G
В первой функции начинает выполняться инструкция 4: но на месте аргумента стоит знак операции "умножение".
Опять вызывается функция tree со строкой "CD*E+AB+*#FG*-" (при каждой отрисовке символа решетка сдвигается на один символ влево)

И так далее. В конце получаем дерево след. вида:
Код:
                            -
                           / \
                          /   \
                         /     \
                        /       \
                        *        *      
                       / \      / \
                      /   \    /   \
                     /     \   F    G 
                    /       \
                   +         +
                  / \       / \
                 /   \     /   \
                A     B   *     E
                         / \
                        /   \
                       С     D

Последний раз редактировалось Trotil; 23.10.2005 в 18:02.
Trotil вне форума  
Старый 23.10.2005, 19:57     # 4
Sam Dark
Member
 
Аватар для Sam Dark
 
Регистрация: 03.07.2003
Адрес: Voronezh, Russia
Пол: Male
Сообщения: 294

Sam Dark МолодецSam Dark МолодецSam Dark Молодец
Спасибо. Попробую реализовать такой алгоритм.
__________________
Это жжжж неспроста...
Sam Dark вне форума  


Ваши права в разделе
Вы НЕ можете создавать новые темы
Вы не можете отвечать в темах.
Вы НЕ можете прикреплять вложения
Вы НЕ можете редактировать свои сообщения

BB код Вкл.
Смайлы Вкл.
[IMG] код Выкл.
HTML код Выкл.

Быстрый переход


Часовой пояс GMT +4, время: 00:32.




Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.