NOJ- 逆波兰表达式-西工大数据结构

    这题想了挺长时间,刚开始用了3个栈,很复杂,最后也过了,想了想改成了两个栈,简单了许多。题目如下:

    逆波兰表达式,就是抽成又向无环图的后续遍历,其中符号的优先级比较难处理,情况很多。

    我的实现如下:

#include <stdio.h>
#include <stdlib.h>

struct charStack
{
    union
    {
        char data[300];
        int pos[300];
    };
    int top;
};

struct orientedGraphNode
{
    char data;
    int left;
    int right;
};

struct orientedGraph
{
    struct orientedGraphNode L[300];
    int n;
};

void run();
void putInDatas();
void getRPNGraph();
int typeJudge(char c);
void pushBack(int pos);
int createNewNode();
int findLetterPosition(char c);
int findSymbolPosition(char c, int left,int right);
void pushSymbolStack(struct charStack *S, char c);
void pushPositionStack(struct charStack *S, int position);
void popStack(struct charStack *S);
void putOut();
void postorderTraversal(int n);

struct orientedGraph gList;
struct charStack lStack, sStack;
char s[300];
int len;

int main()
{
    run();
    return 0;
}

void run()
{
    putInDatas();
    getRPNGraph();
    putOut();
}

void putInDatas()
{
    char c;
    len = -1;
    while((c = getchar()) != '\n')
    {
        len++;
        s[len] = c;
    }
}

void getRPNGraph()
{
    int i, pos;
    for(i = 0; i <= len; i++)
    {
        switch(typeJudge(s[i]))
        {
            case 0 :
            {
                pushBack(findLetterPosition(s[i]));
                break;
            }
            case 1 :
            {
                if(sStack.top >= 0 && (sStack.data[sStack.top] == '+' || sStack.data[sStack.top] == '-'))
                {
                    pos = createNewNode();
                    pushBack(pos);
                }
                pushSymbolStack(&sStack, s[i]);
                break;
            }
            case 2 :
            {
                pushSymbolStack(&sStack, s[i]);
                break;
            }
            case 3 :
            {
                if (sStack.data[sStack.top] != '(')
                {
                    pos = createNewNode();
                    popStack(&sStack);
                    pushBack(pos);
                }
                else
                {
                    popStack(&sStack);
                }
            }
        }
    }
    if (sStack.top >= 0) createNewNode();
}

int typeJudge(char c)
{
    if (c >= 'a' && c <= 'z') return 0;
    if (c == '+' || c == '-') return 1;
    if (c == '*' || c == '/' || c == '(') return 2;
    if (c == ')') return 3;
    return -1;
}

void pushBack(int pos)
{
    pushPositionStack(&lStack, pos);
    if(sStack.top >= 0 && (sStack.data[sStack.top] == '*' || sStack.data[sStack.top] == '/'))
    {
        pos = createNewNode();
        pushBack(pos);
    }
}

int createNewNode()
{
    int pos;
    if(!(pos = findSymbolPosition(sStack.data[sStack.top], lStack.data[lStack.top - 1], lStack.data[lStack.top])))
    {
        pos = ++(gList.n);
        gList.L[gList.n].data = sStack.data[sStack.top];
        gList.L[gList.n].left = lStack.pos[lStack.top - 1];
        gList.L[gList.n].right = lStack.pos[lStack.top];
    }
    popStack(&sStack);
    popStack(&lStack);
    popStack(&lStack);
    return pos;
}

int findLetterPosition(char c)
{
    int i;
    for(i = 1; i <= gList.n; i++)
    {
        if(c == gList.L[i].data) return i;
    }
    gList.L[++(gList.n)].data = c;
    return gList.n;
}

int findSymbolPosition(char c, int left,int right)
{
    int i;
    for(i = 1; i <= gList.n; i++)
    {
        if(c == gList.L[i].data && left == gList.L[i].left && right == gList.L[i].right) return i;
    }
    return 0;
}

void pushSymbolStack(struct charStack *S, char c)
{
    S->data[++(S->top)] = c;
}

void pushPositionStack(struct charStack *S, int position)
{
    S->pos[++(S->top)] = position;
}

void popStack(struct charStack *S)
{
    --(S->top);
}

void putOut()
{
    postorderTraversal(gList.n);
    printf("\n");
}

void postorderTraversal(int n)
{
    if (gList.L[n].left) postorderTraversal(gList.L[n].left);
    if (gList.L[n].right) postorderTraversal(gList.L[n].right);
    printf("%c", gList.L[n].data);
}

    各函数的注释如下:

void run()
{
    putInDatas();//输入数据
    getRPNGraph();//键图
    putOut();//输出
}
void putInDatas()
{
    char c;
    len = -1;
    while((c = getchar()) != '\n')//遍历输入
    {
        len++;
        s[len] = c;
    }
}
void getRPNGraph()
{
    int i, pos;
    for(i = 0; i <= len; i++)//遍历
    {
        switch(typeJudge(s[i]))
        {
            case 0 ://字母
            {
                pushBack(findLetterPosition(s[i]));//再入栈
                break;
            }
            case 1 ://+-
            {
                if(sStack.top >= 0 && (sStack.data[sStack.top] == '+' || sStack.data[sStack.top] == '-'))//若前一个符号是+-
                {
                    pos = createNewNode();//就用前一个符号构建
                    pushBack(pos);//再入栈
                }
                pushSymbolStack(&sStack, s[i]);//符号入栈
                break;
            }
            case 2 ://*/()
            {
                pushSymbolStack(&sStack, s[i]);//符号入栈
                break;
            }
            case 3 ://)
            {
                if (sStack.data[sStack.top] != '(')//若上一个不是(
                {
                    pos = createNewNode();//根据括号里建图
                    popStack(&sStack);//(出栈
                    pushBack(pos);//再入栈
                }
                else//若上一个是(,说明为(x)格式,括号无用
                {
                    popStack(&sStack);//(出栈
                }
            }
        }
    }
    if (sStack.top >= 0) createNewNode();//若还有一步运算,建图
}
int typeJudge(char c)
{
    if (c >= 'a' && c <= 'z') return 0;//转换
    if (c == '+' || c == '-') return 1;
    if (c == '*' || c == '/' || c == '(') return 2;
    if (c == ')') return 3;
    return -1;
}
void pushBack(int pos)
{
    pushPositionStack(&lStack, pos);//字母位置入栈
    if(sStack.top >= 0 && (sStack.data[sStack.top] == '*' || sStack.data[sStack.top] == '/'))//若前面是*/
    {
        pos = createNewNode();//据*/建图
        pushBack(pos);//再入栈
    }
}
int createNewNode()
{
    int pos;
    if(!(pos = findSymbolPosition(sStack.data[sStack.top], lStack.data[lStack.top - 1], lStack.data[lStack.top])))//若无找到已有操作
    {
        pos = ++(gList.n);//创建新节点,赋值
        gList.L[gList.n].data = sStack.data[sStack.top];
        gList.L[gList.n].left = lStack.pos[lStack.top - 1];
        gList.L[gList.n].right = lStack.pos[lStack.top];
    }
    popStack(&sStack);//出栈
    popStack(&lStack);
    popStack(&lStack);
    return pos;//返回位置
}
int findLetterPosition(char c)
{
    int i;
    for(i = 1; i <= gList.n; i++)//遍历寻找
    {
        if(c == gList.L[i].data) return i;
    }
    gList.L[++(gList.n)].data = c;
    return gList.n;
}

int findSymbolPosition(char c, int left,int right)
{
    int i;
    for(i = 1; i <= gList.n; i++)//遍历寻找
    {
        if(c == gList.L[i].data && left == gList.L[i].left && right == gList.L[i].right) return i;
    }
    return 0;
}
//栈操作
void pushSymbolStack(struct charStack *S, char c)
{
    S->data[++(S->top)] = c;
}

void pushPositionStack(struct charStack *S, int position)
{
    S->pos[++(S->top)] = position;
}

void popStack(struct charStack *S)
{
    --(S->top);
}
//后序输出
void putOut()
{
    postorderTraversal(gList.n);
    printf("\n");
}

void postorderTraversal(int n)
{
    if (gList.L[n].left) postorderTraversal(gList.L[n].left);
    if (gList.L[n].right) postorderTraversal(gList.L[n].right);
    printf("%c", gList.L[n].data);
}
    以上就是我的实现。感觉这次写的很垃圾,思路不太清晰,比较繁琐。。。








猜你喜欢

转载自blog.csdn.net/qq_30180107/article/details/80379395