中缀表达式转换成后缀表达式

/**
写一个程序将中缀表达式转换成后缀表达式(后缀表达式不应包括小括号),
该中缀表达式包括+, -, *, /, **(求幂), %, (, ),空格,tab字符, 以及普通整数,
要求通过标准输入接收一个长度不超过16M的字符串做为中缀表达式,将转换后的表达式输出到标准输出.

转换原则:
中缀表达式a + b*c + (d * e + f) * g,其转换成后缀表达式则为a b c * + d e * f  + g * +。
转换过程需要用到栈,具体过程如下:
1)如果遇到操作数,我们就直接将其输出。
2)如果遇到操作符,则我们将其放入到栈中,遇到左括号时我们也将其放入栈中。
3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止。注意,左括号只弹出并不输出。
4)如果遇到任何其他的操作符,如(“+”, “*”,“(”)等,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为止。弹出完这些元素后,才将遇到的操作符压入到栈中。有一点需要注意,只有在遇到" ) "的情况下我们才弹出" ( ",其他情况我们都不会弹出" ( "。也就是说这种操作," + "的优先级最低," ( "优先级最高。
5)如果我们读到了输入的末尾,则将栈中所有元素依次弹出。

参考:
http://blog.csdn.net/ssjhust123/article/details/8001651

*/

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stack>



using namespace std;

bool check ( char* input, int size );
int InfixToSuffix ( char* , int ) ;


int main ( int argc, char* argv[] )
{
    char *input;
    int size = 0;

    if ( argc > 1 ) {

        for ( int i = 1; i < argc; ++i ) {
            // printf ( "参数%d  :  %s   %d\n", i, argv[i], strlen ( argv[i] ) );
            size += strlen ( argv[i] );
        }

        input = ( char * ) calloc ( size, sizeof ( char ) );

        int ite = 0;
        for ( int i = 1; i < argc; ++i ) {
            int len = strlen ( argv[i] );
            for ( int j = 0; j < len; ++j ) {
                input[ite++] = argv[i][j];
            }
        }
    } else {
        printf ( "please input the expression !!!!\n" );
		return 0;
    }

    if ( !check ( input, size ) )
        return 0;
    InfixToSuffix ( input, size );


    free ( input );

#ifdef _WIN32
    system ( "pause" );
#endif

    return 0;

}




int prior ( char op )
{
    if ( op == '+' || op == '-' ) {
        return 1;
    }

    if ( ( op == '*' ) ||
         ( op == '/' ) ||
         ( op == '%' ) ) {
        return 2;
    }

    if ( op == '#' ) {
        return 3;
    }

    if ( op == '(' ) {
        return 0;
    }

    return 0;
}

int my_print ( char data )
{
    if ( data == '#' ) {
        printf ( " ** " );
    } else {
        printf ( " %c ", data );
    }

    return 0;

}

bool check ( char* input, int size )
{
    int i = 0;

    for ( ; i < size - 1; i++ ) {
        if ( prior ( input[i] ) && prior ( input[i + 1] ) ) {
            if ( ( input[i] ) == '*' &&  input[i + 1]  == '*' ) {
                if ( input[i - 1] == '*' ) {// '***'
                    printf ( "\n\t%c%c%c is invalid input\n", input[i - 1], input[i], input[i + 1] );
                    return 0;
                }

            } else {
                printf ( "\n\t%c%c is invalid input\n", input[i], input[i + 1] );
                return 0;
            }
        }
    }
    return 1;
}

void compare_operator ( stack<char> & operator_list, int level )
{
    while ( operator_list.size() ) {
        char temp = operator_list.top();

        if ( prior ( temp ) > level ) {
            my_print ( temp );
            operator_list.pop();
        } else {
            break;
        }
    }
    return;
}



int InfixToSuffix ( char* input, int size )
{
    stack <char> store_operator;

    printf ( "=============================================================================\n" );
    printf ( "Result as follows,\n" );

    int i = 0;
    if ( input[0] == '-' || input[0] == '+' ) {  // 判断第一个字符 是否是 '-' or '+',
        printf ( "%c", input[0] );
        i = 1;
    }
    // process ..
    for ( ; i < size; ++i ) {
        char sw = input[i];

        if ( isalnum ( sw ) || ( sw == '.' ) ) {
            printf ( "%c", sw );
            continue;
        }

        if ( isspace ( sw ) ) {
            continue;
        }


        if ( sw == '(' ) {
            store_operator.push ( sw );
            printf ( " " );
            continue;
        }

        if ( sw == ')' ) {
            if ( !store_operator.size() ) {
                printf ( "处理有错误,或输入有错误%d\n", __LINE__ );
                return 1;
            }

            while ( store_operator.size() ) {
                char temp = store_operator.top();
                store_operator.pop();

                if ( temp == '(' ) {
                    break;
                }

                my_print ( temp );
            }
            continue;
        }

        if ( sw == '-' || sw == '+') {

            char temp = input[i - 1];

            if ( temp == '(' || ( temp == '*' && input[i - 2] == '*' ) ) {
                printf ( " %c", sw );

                temp = input[i + 1];
                while ( temp ) { // 输出整个正/负数 (+/-XXX)
                    if ( isalnum ( temp ) || ( temp == '.' ) ) {
                        printf ( "%c", temp );
                    } else {
                        break;
                    }
                    i++;
                    if ( ( i + 1 ) >= size ) {
                        printf ( "The expression has error!!!!!!!!! \n" );
                        return 0;
                    } else {
                        temp = input[i + 1];
                    }

                }
                continue;
            }
            compare_operator ( store_operator, 0 );
            store_operator.push ( sw );
            printf ( " " );
            continue;
        }

        if ( sw == '*' || sw == '/' || sw == '%' ) {
            char temp = input[i + 1];
            bool flag = false;
            if ( temp == '*' ) { // for '**', use ‘#’ replace ‘**’
                i++; //
                flag = true;
                compare_operator ( store_operator, 2 );
            } else {
                compare_operator ( store_operator, 1 );
            }

            if ( flag ) {
                store_operator.push ( '#' );
            } else {
                store_operator.push ( sw );
            }
            printf ( " " );
            continue;
        }

        if ( sw ) { //
            printf ( "\nThe %c is invalid input, please input again!!!!\n", sw );
            return 0;
        }

    }

    while ( store_operator.size() ) {
        char temp =  store_operator.top();
        my_print ( temp );

        store_operator.pop();
    }

    printf ( "\n=============================================================================\n" );


    return 0;

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值