Преобразование выражения к Обратной Польской НотацииDelphi , Синтаксис , Математика
Автор: Avr555 { **** UBPFD *********** by delphibase.endimus.com **** >> Для работы функции необходимо определить тип: type OperList = array of widestring; Параметром функции служит массив из переменных и операторов. Результат - массив из переменных и операторов Зависимости: SysUtils Автор: avr555, avr555@mail.ru, ICQ:15782989 Copyright: Переделано с http://algolist.manual.ru/syntax/revpn.php Дата: 26 мая 2002 г. ***************************************************** } function ConvertToRPN(AStr: OperList): OperList; var i, k: integer; Stack: OperList; //Stack AResult: OperList; //Tmp for result function Prior(AOper: widestring): integer; begin {Приоритет операции: NOT - 8 унарный "-" - 7 "*", "/" - 6 "+", "-" - 5 ">", "<", "=", "<>", ">=", "<=" - 4 "AND" - 3 "OR" - 2 "(", ")" - 1 } AOper := trim(AOper); result := -1; if AOper = 'NOT' then Result := 8; if (AOper = '*') or (AOper = '/') then Result := 6; if (AOper = '+') or (AOper = '-') then Result := 5; if (AOper = '>') or (AOper = '<') or (AOper = '<>') or (AOper = '>=') or (AOper = '<=') or (AOper = '=') then Result := 4; if AOper = 'AND' then Result := 3; if AOper = 'OR' then Result := 2; if (AOper = '(') or (AOper = ')') then Result := 1; end; procedure AddToStack(AOper: widestring); begin {Добавление элементы в стек} SetLength(Stack, High(Stack) + 2); Stack[High(Stack)] := AOper; end; procedure AddToResult(AOper: widestring); begin SetLength(AResult, High(AResult) + 2); AResult[High(AResult)] := AOper; end; begin {Конвертирование строку в Обратную Польскую Нотацию Возвращает - массив Алгоритм: а) если стек пуст, то опеpация из входной стpоки пеpеписывается в стек; б) опеpация выталкивает из стека все опеpации с большим или pавным пpиоpитетом в выходную стpоку; в) если очеpедной символ из исходной стpоки есть откpывающая скобка, то он пpоталкивается в стек; г) закpывающая кpуглая скобка выталкивает все опеpации из стека до ближайшей откpывающей скобки, сами скобки в выходную стpоку не пеpеписываются, а уничтожают дpуг дpуга. } Result := nil; AResult := nil; i := 0; while i <= High(AStr) do begin if Prior(AStr[i]) = -1 then //Значит просто переменная AddToResult(AStr[i]) else //Операции begin if High(Stack) = -1 then {a} AddToStack(AStr[i]) else begin if AStr[i] = '(' then {в} AddToStack(AStr[i]) else begin if AStr[i] = ')' then {г} begin k := High(Stack); while (k >= 0) and (Stack[k] <> '(') do begin AddToResult(Stack[k]); SetLength(Stack, High(Stack)); //Удаляем элемент из стека k := k - 1; end; //Удаляем открывающуюся скобку SetLength(Stack, High(Stack)); //Удаляем элемент из стека end else begin k := High(Stack); while (k >= 0) and (Prior(Stack[k]) >= Prior(AStr[i])) do {б} begin AddToResult(Stack[k]); SetLength(Stack, high(Stack)); //Удаляем элемент из стека k := k - 1; end; AddToStack(AStr[i]); //Если не скобка просто добавляем в стек end; end; end; end; i := i + 1; end; //while //Сбрасываем все оставшееся из стека for i := high(Stack) downto 0 do begin AddToResult(Stack[i]); end; result := AResult; end; Пример использования: procedure test; var s, s1: widestring; tmp, rtmp: OperList; i: integer; begin s := '(A+B)*(C+D)-E'; tmp := nil; rtmp := nil; for i := 1 to Length(S) do begin SetLength(tmp, high(tmp) + 2); tmp[high(tmp)] := S[i]; end; rtmp := ConvertToRPN(tmp); s1 := ''; for i := 1 to High(rtmp) do begin s1 := s1 + rtmp[i]; end; end; Перевод контента на русский язык: Функции и процедуры
Основной алгоритм
Конвертирующий процесс涉гает следующие шаги:
1. Инициализируйте пустой стек (Stack) и пустой массив результатов (AResult).
2. Перейдите по выражению входного параметра (AStr). Для каждого элемента:
* Если это переменная (т.е., не оператор), добавьте ее в массив результатов.
* Если это оператор, проверьте его приоритет с помощью функции Пример использования
Предоставленный пример демонстрирует, как использовать эту функцию для конвертации выражения из инфиксной нотации в RPN. Он определяет процедуру Предложения по улучшению
* Рассмотрите добавление обработки ошибок для недопустимых входных выражений.
* Вы можете улучшить код, используя более описательные имена переменных и комментарии к сложной логике.
* Вместо использования стека в виде массива можно использовать динамический массив или связанный список для улучшения эффективности реализации.
* Функция Преобразование выражения в Обратную Польскую Нотацию (RPN) - это процесс, при котором исходное выражение преобразуется в последовательность операторов и переменных, соответствующую порядку выполнения операций. Комментарии и вопросыПолучайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта. :: Главная :: Математика ::
|
||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |