简体   繁体   English

在C ++中使用堆栈模板类解析括号

[英]Parsing Parenthesis using stack template class in C++

I have a homework and its just bugging for the last 2 days, I've been doing exactly what the pseudo code and still haven't got it right yet. 我有一个作业,并且在最近的两天里一直在窃听,我一直在做伪代码,但是仍然没有正确。 For example, if I put in "mike]" or "mike]123", my program will crash, due to the stack is empty...From what I observe, the program will crash when: - The stack is empty - And there is a close parenthesis PS: with the help of us2012, I can fix the crash problem. 例如,如果我输入“ mike]”或“ mike] 123”,则由于堆栈为空,我的程序将崩溃...根据我的观察,该程序将在以下情况下崩溃:-堆栈为空-并且附上一个括号:PS:在us2012的帮助下,我可以解决崩溃问题。 However, the result is not right. 但是,结果不正确。 Instead of printing out "invalid", it outputs "valid" 而不是打印出“无效”,它输出“有效”

:( :(

Here is the pseudo code from my professor: 这是我教授的伪代码:

def parse_parenthesis(str):
    stack = create a new empty stack of OpenParen objects
    for i from 0 to str.size() - 1:
        if str[i] is an open parenthesis
            stack.push(new OpenParen(str[i]))
        else if str[i] is not a close parenthesis:
            # str[i] is not a parenthesis of any kind, so ignore it
            continue
        # otherwise str[i] must be a close parenthesis, try to
        # match it with the most recent open paren, on the top
        # of the stack
        else if stack is empty
        return false;
        else if stack.peek() is of the same type as str[i]:
        # close properly
        stack.pop()
        else
        return false;
    if stack is not empty
        return false;
    else
        return true

and here is what I have so far: 这是我到目前为止所拥有的:

.cpp file .cpp文件

bool ParenMatching(const string& s, unique_ptr<string>& output)
{
    unique_ptr<OpenParen> stack(new OpenParen);

    bool validOpen, validClose, valid;
    bool match; //haveCloseParen;
    /*string unMatch = "Unmatch";
    string unExpected = "Unexpected close paren";
    string noError = "No Error";*/

    for (size_t i = 0; i < s.length(); i++)
    {
        // check if its open parenthesis
        validOpen = stack->IsOpenParen(s[i]);
        // check if its close parenthesis
        validClose = stack->IsCloseParen(s[i]);

        // if there is open paren, push into the stack
        if(validOpen)
            stack->PushObj(s[i]);
        else if(!validClose)
        {
            continue;
        }
            else if(stack->GetObj().IsEmpty())
            valid = false;      
        else if(match = IsMatchParen(s[i], stack))
            stack->PopObj();            
        else
            valid = false;
    }

    if(!stack->GetObj().IsEmpty())
        valid = false;
    else
        valid = true;
    return valid;
}

bool IsMatchParen(const char c, const unique_ptr<OpenParen>& stack)
{   
    bool valid;
    if(c == ')' && stack->PeekObj() == '(')
        valid = true;
    else if (c == ']' && stack->PeekObj() == '[')
        valid = true;
    else if (c == '}' && stack->PeekObj() == '{')
        valid = true;
    else if (c == '>' && stack->PeekObj() == '<')
        valid = true;
    else
        valid = false;
    return valid;
}

OpenParen.cpp OpenParen.cpp

// Check if its open paren
bool OpenParen::IsOpenParen(const char c)
{
    bool isOpen;
    if(c == '(' || c == '[' || c == '{' || c == '<')
        isOpen = true;
    else
        isOpen = false;
    return isOpen;
}

// check if its close paren
bool OpenParen::IsCloseParen(const char c)
{
    bool isClose;
    if(c == ')' || c == ']' || c == '}' || c == '>')
        isClose = true;
    else
        isClose = false;
    return isClose;
}

One important thing you should keep in mind about C++ : Multiple else if s do not live at the same level. 关于C ++,您应该牢记一件事: else if s 不在同一级别,则应考虑多个else if That's because else if is not a single entity, it's an else that belongs to the preceding statement and an if that begins a new statement, so 那是因为else if不是一个单一的实体,它是一个属于前面的语句的else ,而if是一个新语句的开始,所以

if (cond1)
 a();
else if (cond 2)
 b();
else if (cond 3)
 c();
else
 d();

is actually 实际上是

if (cond1)
 a();
else { 
  if (cond 2)
   b();
  else {
    if (cond 3)
     c();
    else
     d();
  }
}

Therefore, your check whether the stack is empty needs to be before the check whether the current close parens matches the top of the stack. 因此,您需要检查堆栈是否为空, 然后再检查当前的封闭状态是否与堆栈顶部匹配。 Otherwise, your program will try to examine the top of the stack when it's empty, and that results in a crash. 否则,您的程序将尝试在栈顶为空时检查栈顶,这将导致崩溃。


Also, setting valid = false is not the right thing to do when you find a condition that indicates a non-match. 同样,当您发现表示不匹配的条件时,将valid = false设置valid = false也不是正确的选择。 The loop will still continue and can reset valid to true in a later iteration. 循环仍将继续,并且可以在以后的迭代中将valid重置为true You need to immediately return false , as you can already see in your pseudocode. 您需要立即return false ,就像您在伪代码中已经看到的那样。

gcc 4.7.3: g++ -Wall -Wextra -std=c++0x parens.cpp gcc 4.7.3:g ++ -Wall -Wextra -std = c ++ 0x parens.cpp

#include <iostream>
#include <stack>
#include <string>
#include <vector>

bool isOpen(char c) {
  return c == '(' || c == '[' || c == '{' || c == '<'; }

bool isClose(char c) {
  return c == ')' || c == ']' || c == '}' || c == '>'; }

bool isMatch(char c1, char c2) {
  return (c1 == '(' && c2 == ')')
      || (c1 == '[' && c2 == ']')
      || (c1 == '{' && c2 == '}')
      || (c1 == '<' && c2 == '>'); }

bool parse(const std::string& s) {
  std::stack<std::string::value_type> stk;

  for (std::string::size_type i = 0; i < s.size(); ++i) {
    if (isOpen(s[i])) { stk.push(s[i]); }
    else if (isClose(s[i])) {
      if (!stk.empty() && isMatch(stk.top(), s[i])) { stk.pop(); }
      else { return false; } } }

  return stk.empty(); }

int main() {
  std::vector<std::string> ptests = {
      "", "()", "()()", "(())", "a(a)a" };
  std::vector<std::string> ftests = {
      "(", ")", ")(", ")()(", "))((" };

  for (const auto& t : ptests) {
    if (!parse(t)) { std::cout << "fail: " << t << std::endl; } }

  for (const auto& t : ftests) {
    if (parse(t)) { std::cout << "fail: " << t << std::endl; } }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM