128 lines
3.8 KiB
C
128 lines
3.8 KiB
C
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#define BUFFER_SIZE 255
|
||
#define STACK_SIZE 255
|
||
|
||
char oper[STACK_SIZE] = {0}; // стек для операций + - * / ( )
|
||
int oend=0; // заполненность стека
|
||
|
||
void printStack(void)
|
||
{
|
||
for(int i = 0;i<oend;i++)
|
||
{
|
||
printf("Stack: %c ",oper[i]);
|
||
}
|
||
printf("\n");
|
||
}
|
||
|
||
void push(char v) {
|
||
oper[oend++] = v;
|
||
//~ printStack();
|
||
}
|
||
char pop() {
|
||
if(oend<=0 || oend>=BUFFER_SIZE) {
|
||
fprintf(stderr,"Stack overflow\n");
|
||
exit(1);
|
||
}
|
||
oend--;
|
||
//~ printStack();
|
||
return oper[oend];
|
||
}
|
||
_Bool emptyStack() {
|
||
return oend==0;
|
||
}
|
||
_Bool isOperator(char c) {
|
||
return c=='+' || c=='-' || c=='*' || c=='/';
|
||
}
|
||
int priority(char c) {
|
||
if(c=='+' || c=='-')
|
||
return 1;
|
||
if(c=='*' || c=='/')
|
||
return 2;
|
||
return 0;
|
||
}
|
||
|
||
int main(void)
|
||
{
|
||
char c;
|
||
int pos=0;
|
||
|
||
char answer[BUFFER_SIZE]={0};
|
||
for(int i=0;i<BUFFER_SIZE;i++)
|
||
answer[i]=0;
|
||
printf("Input infix string: ");// ( 3 + 5 ) * 10 - 2 * 7
|
||
char str[1000]; //Answer: 3 5 + 10 * 2 7 * -
|
||
int len=0;
|
||
while((c=getchar())!='\n')//scanf("[^\n]",%s);
|
||
str[len++]=c;
|
||
str[len]=0;
|
||
for(int i=0;i<len;i++)
|
||
{
|
||
//Если токен — число, то добавить его в очередь вывода
|
||
if(str[i]>='0' && str[i]<='9')//isDigit(str[i])
|
||
{
|
||
int number,size=0;
|
||
for(number=0;str[i]>='0' && str[i]<='9';i++,size++)
|
||
{
|
||
number=number*10+str[i]-'0';
|
||
}
|
||
sprintf(answer+pos,"%d ",number);
|
||
//~ printf("%d \n",number);
|
||
pos += size+1;
|
||
}
|
||
else
|
||
{
|
||
if(i>=len)
|
||
break;
|
||
c = str[i];
|
||
//Если токен — оператор op1
|
||
if(isOperator(c))
|
||
{
|
||
//Пока присутствует на вершине стека токен оператор op2, чей приоритет выше или равен приоритету op1
|
||
while( !emptyStack() )
|
||
{
|
||
char top = pop();
|
||
if(priority(top)>=priority(c))
|
||
{
|
||
//Переложить op2 из стека в выходную очередь
|
||
sprintf(answer+pos,"%c ",top);
|
||
pos += 2;
|
||
} else
|
||
{ // isOperator(top) == false
|
||
push(top);
|
||
break;
|
||
}
|
||
}
|
||
//Положить op1 в стек
|
||
push(c);
|
||
}
|
||
//Если токен — открывающая скобка, то положить его в стек
|
||
else if( c=='(' )
|
||
{
|
||
push(c);
|
||
}
|
||
//Если токен — закрывающая скобка:
|
||
else if( c==')' )
|
||
{
|
||
//Пока токен на вершине стека не открывающая скобка
|
||
while( (c=pop()) != '(' )
|
||
{
|
||
//Переложить оператор из стека в выходную очередь.
|
||
sprintf(answer+pos,"%c ",c);//*pos++ = c,*pos++ = ' ';
|
||
//~ printf("%c \n",c);
|
||
pos += 2;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//Если больше не осталось токенов на входе
|
||
//Пока есть токены операторы в стеке:
|
||
while( !emptyStack() )
|
||
{
|
||
sprintf(answer+pos,"%c ", pop());//Переложить оператор из стека в выходную очередь
|
||
pos += 2;
|
||
}
|
||
printf("Answer: %s\n",answer);
|
||
return 0;
|
||
}
|