Польський інверсний запис
![]() |
Зворо́тний по́льський за́пис (зворотний бездужковий запис, постфіксна нотація, польський інверсний запис (ПОЛІЗ), англ. RPN — Reverse Polish Notation) — форма запису математичних виразів, в якій знаки операцій розташовано після операндів. Розташування знаків операцій перед операндами використовує польська нотація.
Історія розробки[ред. | ред. код]
Зворотій польський запис був розроблений австралійським філософом і фахівцем в області теорії обчислювальних машин Чарльзом Хембліном в середині 1950-х на основі польської нотації, яка була запропонована в 1920 польським математиком Яном Лукашевичем. Робота Хембліна була представлена на конференції в червні 1957, і видана в 1957 і 1962.
Першими комп'ютерами, що підтримують зворотний польський запис були KDF9 від English Electric Company, який був випущений в 1963, і американський Burroughs B5000, випущений в тому ж 1963. Зворотна польська нотація застосовувалася в радянському інженерному калькуляторі Б3-19М, випущеному в 1976 році.Майже всі програмовані калькулятори в СРСР аж до кінця 1980-х років використовували ПОЛІЗ - він простіше реалізовувалася і дозвов обійтися в програмуванні обчислень меншим числом команд, в порівнянні із звичайною алгебраїчної нотацією, адже кількість програмної пам'яті в цих моделях завжди було критичним ресурсом.[1]
Загальний вигляд[ред. | ред. код]
У загальному вигляді апис виглядає наступним чином:
- Запис набору операцій складається з послідовності операндів і знаків операцій. Операнди у виразі при письмовому записі розділяються пробілами.
- Вираз читається зліва направо. Коли у виразі зустрічається знак операції, виконується відповідна операція над двома останніми перед ним операндами в порядку їх запису. Результат операції замінює у вираженні послідовність її операндів і її знак, після чого вираз обчислюється далі за тим же правилом.
- Результатом обчислення виразу стає результат останньої обчисленої операції.[1]
Приклади[ред. | ред. код]
Вираз | Традиційна (інфіксна) нотація | Зворотна польська (постфіксна) нотація |
---|---|---|
a + b × c | a + b*c | a b c * + |
(a + b) × (c + d) | (a + b) * (c + d) | a b + c d + * |
(a + t) × (b × (a + c))(c + d) | (a + t) * (b * (a + c))^(c + d) | a t + b a c + * c d + ^ * |
Застосування[ред. | ред. код]
Зворотний польський запис є зручним для застосування в обчислювальних пристроях. Наприклад, для обчислення виразу
- a + b
слід виконати такі дії:
- обчислити a
- обчислити b
- скласти результати
Саме така послідовність і задається польським інверсним записом:
- a b +
Завдяки цьому ПОЛІЗ здобув досить широке розповсюдження в інженерних мікрокалькуляторах та мікрокомп'ютерах. Зокрема, такі калькулятори виробляли фірми Hewlett-Packard (HP 9100A), Texas Instruments. Практично всі програмовані калькулятори, що вироблялися в СРСР (Б3-34, MK-52, MK-61 та інші) застосовували зворотну польську нотацію.
Комп'ютерні програми зазвичай під час аналізу формул перетворюють їх на послідовність інструкцій у ПОЛІЗ, і саме в такому порядку вони виконуються.
На основі постфіксної нотації побудовано мову програмування Forth, також вона безпосередньо застосовується у PostScript.
Стековою машиною[en] називається алгоритм, який проводить обчислення за зворотною польською нотацією[джерело?]. Прикладом використання стекової машини є програма UNIX dc.
Алгоритм для обчислення значення виразу[ред. | ред. код]
Для всіх символів виконуємо такі дії:
- Якщо Аі число, то вкласти його у стек;
- Якщо Аі оператор, то:
- Витягуємо зі стека два числа;
- Виконуємо дію із числами і результат вкладаємо в стек;
- Якщо Аі є функцією то:
- Витягуємо зі стека одне число;
- Визначаємо значення функції із відповідним аргументом та поміщаємо результат у стек;
- В кінці роботи в стеку знаходитиметься результат виразу.
Приклад[ред. | ред. код]
Маємо вираз: 12 + 2 * ( ( 3 * 4 ) + ( 10 / 5 ) )
Вираз у польському інверсному записі: 12 2 3 4 * 10 5 / + * +
Порядок дій над ним буде такий:
Крок |
Елемент |
Стек |
1 |
12 |
12 |
2 |
2 |
2 12 |
3 |
3 |
3 2 12 |
4 |
4 |
4 3 2 12 |
5 |
* |
12 2 12 |
6 |
10 |
10 12 2 12 |
7 |
5 |
5 10 12 2 12 |
8 |
/ |
2 12 2 12 |
9 |
+ |
14 2 12 |
10 |
* |
28 12 |
11 |
+ |
40 |
Алгоритм для перетворення звичайного запису в бездужковий[ред. | ред. код]
- Поки ще є символи для зчитування:
- Читаємо наступний символ;
- Якщо символ є числом або постфіксною функцією (наприклад, ! — факторіал), то додаємо до вихідного рядка;
- Якщо символ є префіксною функцією (наприклад, sin — синус), поміщаємо його в стек;
- Якщо символ є '(', поміщаємо його в стек;
- Якщо символ є ')', то:
- До тих пір, поки верхнім елементом стека не стане відкриваюча дужка, виштовхуємо елементи зі стека у вихідний рядок. При цьому відкриваюча дужка видаляється зі стека, але у вихідний рядок не додається. Якщо після цього кроку на вершині стека виявляється символ функції, виштовхуємо його у вихідний рядок. Якщо стек закінчився раніше, ніж ми зустріли відкриваючу дужку, це означає, що у виразі або неправильно поставлений розділовий знак, або неузгодженні дужки.
- Якщо символ є бінарною операцією, тоді:
- 1) поки на вершині стека префіксна функція…
- … АБО операція на вершині стека має більший пріоритет ніж o1
- … АБО операція на вершині стека ліво-асоціативна з пріоритетом як у o1
- … виштовхуємо верхній елемент стека у вихідний рядок;
- 2) поміщаємо операцію o1 у стек;
- Коли вхідний рядок закінчився, виштовхуємо всі символи зі стека у вихідний рядок. У стеку повинні були залишитись тільки символи операцій; якщо це не так, значить у виразі неузгоджені дужки.
Приклад[ред. | ред. код]
Маємо рядок «3 +4 * 2 / (1-5) ^ 2». Потрібно перевести його до польського запису
Читаємо «3» Додаємо «3» до виходу Вихід: 3
Читаємо «+» Вставляємо «+» в стек Вихід: 3 Стек: +
Читаємо «4» Додаємо «4» до виходу Вихід: 3 4 Стек: +
Читаємо «*» Вставляємо «*» в стек Вихід: 3 4 Стек: + *
Читаємо «2» Додаємо «2» до виходу Вихід: 3 4 2 Стек: + *
Читаємо «/» Видаляємо «*» зі стека і додаємо до виходу, вставляємо «/» в стек Вихід: 3 4 2 * Стек: + /
Читаємо «(» Вставляємо «(» в стек Вихід: 3 4 2 * Стек: + / (
Читаємо «1» Додаємо «1», до виходу Вихід: 3 4 2 * 1 Стек: + / (
Читаємо «-» Вставляємо «-» в стек Вихід: 3 4 2 * 1 Стек: + / (-
Читаємо «5» Додаємо «5» до виходу Вихід: 3 4 2 * 1 5 Стек: + / (-
Читаємо «)» Видаляємо «-» зі стека і додаємо до виходу, видаляємо «(» зі стека Вихід: 3 4 2 * 1 5 - Стек: + /
Читаємо «^» Додаємо «^» в стек Вихід: 3 4 2 * 1 5 - Стек: + / ^
Читаємо «2» Додаємо «2» до виходу Вихід: 3 4 2 * 1 5 - 2 Стек: + / ^
Кінець виразу Витягуємо усі елементи зі стека і додаємо до виходу Вихід: 3 4 2 * 1 5 - 2 ^ / +
Див. також[ред. | ред. код]
Посилання[ред. | ред. код]
Ця стаття не містить посилань на джерела. (листопад 2015) |