Загрузка данных
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
struct tstk {
double inf;
tstk *a;
};
struct tstkStr {
char inf[100];
tstkStr *a;
};
tstk *AddStack(tstk *sp, double inf) {
tstk *spt = new tstk;
spt->inf = inf;
spt->a = sp;
return spt;
}
tstk *ReadStack(tstk *sp, double &inf) {
tstk *spt = sp;
inf = sp->inf;
sp = sp->a;
delete spt;
return sp;
}
tstkStr *AddStackStr(tstkStr *sp, char *inf) {
tstkStr *spt = new tstkStr;
strcpy(spt->inf, inf);
spt->a = sp;
return spt;
}
tstkStr *ReadStackStr(tstkStr *sp, char *inf) {
tstkStr *spt = sp;
strcpy(inf, sp->inf);
sp = sp->a;
delete spt;
return sp;
}
int isNumber(char *s) {
if (s[0] == '\0') return 0;
int i = 0;
if (s[0] == '-') i++;
int dot = 0;
for (; s[i]; i++) {
if (s[i] == '.') {
dot++;
if (dot > 1) return 0;
}
else if (s[i] < '0' || s[i] > '9') return 0;
}
return 1;
}
int isOperator(char c) {
return (c == '+' || c == '-' || c == '*' || c == '/');
}
// Разбор строки на токены (аналог strtok без его использования)
int parseTokens(char *str, char tokens[100][100]) {
int n = 0;
int i = 0;
int j = 0;
char token[100];
for (i = 0; str[i] != '\0'; i++) {
if (str[i] == ' ') {
if (j > 0) {
token[j] = '\0';
strcpy(tokens[n++], token);
j = 0;
}
} else {
token[j++] = str[i];
}
}
if (j > 0) {
token[j] = '\0';
strcpy(tokens[n++], token);
}
return n;
}
// Вычисление числового RPN
double calcRPN(char tokens[100][100], int count) {
tstk *sp = NULL;
double a, b;
for (int i = 0; i < count; i++) {
if (isNumber(tokens[i])) {
sp = AddStack(sp, atof(tokens[i]));
}
else if (strlen(tokens[i]) == 1 && isOperator(tokens[i][0])) {
sp = ReadStack(sp, b);
sp = ReadStack(sp, a);
switch (tokens[i][0]) {
case '+': sp = AddStack(sp, a + b); break;
case '-': sp = AddStack(sp, a - b); break;
case '*': sp = AddStack(sp, a * b); break;
case '/': sp = AddStack(sp, a / b); break;
}
}
}
double res;
sp = ReadStack(sp, res);
return res;
}
void OptimizeRPN(char *strin, char *strout) {
tstkStr *sp = NULL;
char tokens[100][100];
int tokCount = parseTokens(strin, tokens);
for (int i = 0; i < tokCount; i++) {
char *tok = tokens[i];
// Если токен - число или переменная (буква)
if (isNumber(tok) || (strlen(tok) == 1 && !isOperator(tok[0]))) {
sp = AddStackStr(sp, tok);
}
// Если токен - оператор
else if (strlen(tok) == 1 && isOperator(tok[0])) {
char b[100], a[100];
sp = ReadStackStr(sp, b);
sp = ReadStackStr(sp, a);
// Проверяем, можно ли вычислить
if (isNumber(a) && isNumber(b)) {
char fragment[100][100];
strcpy(fragment[0], a);
strcpy(fragment[1], b);
strcpy(fragment[2], tok);
double res = calcRPN(fragment, 3);
char resStr[100];
if (res == (int)res) sprintf(resStr, "%d", (int)res);
else sprintf(resStr, "%g", res);
sp = AddStackStr(sp, resStr);
} else {
sp = AddStackStr(sp, a);
sp = AddStackStr(sp, b);
sp = AddStackStr(sp, tok);
}
}
}
// Собираем результат из стека
char temp[100][100];
int cnt = 0;
while (sp != NULL) {
sp = ReadStackStr(sp, temp[cnt++]);
}
strout[0] = '\0';
for (int i = cnt - 1; i >= 0; i--) {
strcat(strout, temp[i]);
if (i > 0) strcat(strout, " ");
}
}
int main() {
char str[200], strp[200];
cout << "Vvedite RPN virazhenie (tokeni cherez probel): ";
cin.getline(str, 200);
OptimizeRPN(str, strp);
cout << "Optimizirovannoe: " << strp << endl;
return 0;
}