【问题标题】:C++ Program to detect if Parenthesis, Brackets and Braces are Balanced - Need to Output Caret Under Errors检测括号、括号和大括号是否平衡的 C++ 程序 - 需要在错误下输出插入符号
【发布时间】:2014-03-17 20:36:19
【问题描述】:

我需要编写一个程序,使用堆栈来验证字符串表达式是否平衡,包括其中包含的括号、方括号和花括号。字符串由用户输入,所有错误(即不匹配的括号、方括号和花括号)都需要在下一行直接在其下方用插入符号指出,如下所示:

(这里有点难以展示...)

(()

^

在我的“平衡”函数中,我正在获取循环的当前索引,并将其分配给“unmatchedRightPosition”或“unmatchedLeftPosition”,无论何时需要。我认为我的很多程序已经可以工作了,但是我在将插入符号放在错误下时遇到了问题。我的教授建议我可以选择使用一个包含结构的堆栈类,其中每个结构都包含一个字符和字符的位置,但我对此有点困惑。

感谢收看

#include <iostream>
#include <string>
#include <stdlib.h>
#include <sstream>

using namespace std;

struct Stack{
    static const unsigned MAX_SIZE = 5;
    char data[ MAX_SIZE ];
    unsigned size;
};

struct Stack2{

 unsigned unmatchedLeftPos, unmatchedRightPos;

};

void initialize( Stack & stack );
void show( const Stack & stack );
unsigned getSize( const Stack & stack );
void push( Stack & stack, char c );
char pop( Stack & stack );
char top( const Stack & stack );
bool die( const string & msg );
bool balanced (unsigned & unmatchedLeftPos, unsigned & unmatchedRightPos, const string & expr);

int main(){


    Stack2 s2;

    cout << "\nPlease enter your expression - enter a blank line to quit. \n";

    for(;;){

        string line;
        getline(cin, line);


        if( line.size() == 0 )  break;

            if (balanced(s2.unmatchedLeftPos, s2.unmatchedRightPos, line) == 1){

                cout << "OK\n";

            }

            else if (balanced(s2.unmatchedLeftPos, s2.unmatchedRightPos, line) == 0){

            cout << string(s2.unmatchedLeftPos, ' ') << '^';
            cout << string(s2.unmatchedRightPos, ' ') << '^';

            }
        }

        return 0;
    }

void initialize( Stack & stack ){
    stack.size = 0;
}

void show( const Stack & stack ){
    cout <<"[" << stack.size <<"]:";
    for(  unsigned i = 0;  i < stack.size;  i++  )
        cout <<stack.data[i];
    cout <<endl;
} // show

unsigned getSize( const Stack & stack ) {return stack.size;}

void push( Stack & stack, char c ){
    if( stack.size == Stack::MAX_SIZE )  die( "push: overflow" );
    stack.data[stack.size++] = c;
} // push

char pop( Stack & stack ){
    if( stack.size == 0 )  die( "pop: underflow" );
    return stack.data[--stack.size];
} // pop

char top( const Stack & stack ){
    if( stack.size == 0 )  die( "top: underflow" );
    return stack.data[stack.size-1];
} // pop

bool die( const string & msg ){
    cerr <<endl <<"Fatal error: " << msg <<endl;
    exit( EXIT_FAILURE );
}

bool balanced (unsigned & unmatchedLeftPos, unsigned & unmatchedRightPos, const string & expr){

    Stack s;
    initialize(s);

    unsigned i;

    for (i = 0; i < expr.size(); i++){

        char c = expr[i];

        if( expr.size() == Stack::MAX_SIZE)  {
                die( "push: overflow" );
            }

        if (c == '(')
        {
            push(s, c);
        }

        else if (c == '['){
            push(s, c);
        }

        else if (c == '{'){
            push(s, c);
        }

        if (s.size == 0 && (c == ')' || c == ']' || c == '}'))

        {
            unmatchedRightPos = i;
            return false;
        }

        else if (c == ')' && top(s) == '('){
            pop(s);
        }

        else if (c == ']' && top(s) == '['){
            pop(s);
        }

        else if (c == '}' && top(s) == '{'){
            pop(s);
        }

    }

    if (s.size == 0){

        return true;
    }

    else if (top(s) == '(' || top(s) == '[' || top(s) == '{'){

        unmatchedLeftPos = i;
        return false;
    }

}

【问题讨论】:

  • 我相信你的教授推荐了一个可以容纳错误的堆栈。每个错误都将保存在一个结构中,其中有一个变量表示它在字符串中发生的位置,可能还有一个 char 来说明哪个字符不正确。要显示插入符号,请创建一个带空格的字符串,并为从堆栈中弹出的每个位置插入一个 ^。

标签: c++


【解决方案1】:

您当前正在使用堆栈,带有一个字符数组:

char data[ MAX_SIZE ];

相反,您会选择一个结构,它在输入字符串中同时保存字符和位置

struct info {
    char data;
    int pos;
};

info data[ MAX_SIZE ];

所以最后,你只需检查你的堆栈,除了无效字符之外,你还有输入字符串中的位置。

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    您可以将 main 移到底部以避免前向函数声明。您也不需要为错误使用另一个堆栈(实际上我认为如果不这样做会更容易)。您只需将支架及其位置都放在一个堆栈上,即

    struct Item
    {
        char bracket;
        size_t position;
    }
    
    std::stack<Item> st;
    

    以及一个数组,或者更好的是初始化为与输入字符串长度相同的字符串,所有空格在遇到错误时更改为'^',即

    std::string errorString(input.size(), ' ');
    
    if ( /* brackets don't match */ )
    {
        errorString[st.top().position] = '^';
    }
    

    如果您不能使用 STL 堆栈,您需要修改自己的以保存 Item 对象而不是 char(即项目数据[MAX_SIZE];)。您的代码看起来非常像 C 认为的那样,如果您改用 std::stringstd::stack 会更好。

    【讨论】:

    • You don't need to declare your methods in advance in C++. That's a C thing. -- 不正确。如果定义在 main 之后(这是 @OP 所拥有的),则代码不会在没有前向声明的情况下编译。在 C 和 C++ 中都是一样的。
    • 啊,对了,我没注意到他的主线在上面。固定。
    猜你喜欢
    • 2022-08-13
    • 1970-01-01
    • 2015-05-01
    • 2019-01-12
    • 2013-06-05
    • 2021-06-05
    • 1970-01-01
    • 2021-09-20
    相关资源
    最近更新 更多