Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C++;_C++_Parsing_Stack_Parentheses - Fatal编程技术网

C++ 在C++;

C++ 在C++;,c++,parsing,stack,parentheses,C++,Parsing,Stack,Parentheses,我有一个家庭作业,它只是在过去的两天窃听,我一直在做什么伪代码,但仍然没有得到它的权利。 例如,如果我输入“mike]”或“mike]123”,我的程序将崩溃,因为堆栈是空的……据我观察,程序将在以下情况下崩溃: -堆栈是空的 -还有一个括号 PS:在us2012的帮助下,我可以修复崩溃问题。然而,结果并不正确。 它不打印“无效”,而是输出“有效” :( 下面是我教授的伪代码: def parse_parenthesis(str): stack = create a new empty

我有一个家庭作业,它只是在过去的两天窃听,我一直在做什么伪代码,但仍然没有得到它的权利。 例如,如果我输入“mike]”或“mike]123”,我的程序将崩溃,因为堆栈是空的……据我观察,程序将在以下情况下崩溃: -堆栈是空的 -还有一个括号 PS:在us2012的帮助下,我可以修复崩溃问题。然而,结果并不正确。 它不打印“无效”,而是输出“有效”

:(

下面是我教授的伪代码:

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
以下是我目前掌握的情况:

.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;
}
bool-ParenMatching(常量字符串&s,唯一\u ptr&output)
{
独特的ptr堆栈(新OpenParen);
bool validOpen,validClose,valid;
bool match;//haveCloseParen;
/*字符串unMatch=“unMatch”;
string unExpected=“unExpected close paren”;
字符串noError=“无错误”*/
对于(大小i=0;iIsOpenParen(s[i]);
//检查其右括号是否正确
validClose=stack->IsCloseParen(s[i]);
//如果有打开的paren,则将其推入堆栈
if(validOpen)
堆栈->PushObj(s[i]);
否则如果(!validClose)
{
继续;
}
else if(stack->GetObj().IsEmpty())
有效=错误;
else if(match=IsMatchParen(s[i],堆栈))
堆栈->PopObj();
其他的
有效=错误;
}
如果(!stack->GetObj().IsEmpty())
有效=错误;
其他的
有效=真;
返回有效;
}
布尔IsMatchParen(常量字符c、常量唯一\u ptr和堆栈)
{   
布尔有效;
如果(c==”)&&stack->PeekObj()==”(”)
有效=真;
else if(c==']'&&stack->PeekObj()=='[')
有效=真;
else if(c=='}'&&stack->PeekObj()=='{')
有效=真;

else if(c=='>'&&stack->PeekObj()=``p>一个重要的事情,你应该牢记C++:多个<代码>否则,如果< /Calp>S >强>不/强>同住。这是因为<代码>否则如果不是单个实体,则是<前述语句> <代码> > <代码>如果< /代码>开始新语句,那么

if (cond1)
 a();
else if (cond 2)
 b();
else if (cond 3)
 c();
else
 d();
实际上是

if (cond1)
 a();
else { 
  if (cond 2)
   b();
  else {
    if (cond 3)
     c();
    else
     d();
  }
}
因此,在检查当前关闭参数是否与堆栈顶部匹配之前,需要先检查堆栈是否为空。否则,当堆栈为空时,程序将尝试检查堆栈顶部,这将导致崩溃



此外,当您发现一个指示不匹配的条件时,设置
valid=false
不是正确的做法。循环仍将继续,并且可以在以后的迭代中将
valid
重置为
true
。您需要立即
返回false
,正如您在伪代码中已经看到的那样。

#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; } }
}
#包括
#包括
#包括
#包括
布尔等参(字符c){
返回c='('| c='['| c=='{'| c==''''.}
布尔isMatch(字符c1,字符c2){
返回(c1='('&&c2=')'))
||(c1=='['&&c2==']')
||(c1='{'&&c2='}')
||(c1='';}
bool解析(const std::string&s){
std::堆栈stk;
对于(std::string::size_type i=0;iif(!parse(t)){std::cout这真的有点太多的代码了,不希望我们调试所有代码。请尝试将问题本地化,并使您的问题描述更详细。感谢您的建议。我确实删除了一些我认为与我的问题无关的代码。请看一看,看看我做错了什么。
OpenParem::IsOpenParen
could可以实现为只返回c=='(“| | c==”[“| | c==”{'| | c=='我同意,除非有更多的东西需要某种对象来维护状态,否则我会将其作为自由函数来实现。我喜欢看到人们使用智能指针,但在这种情况下使用
unique_ptr
完全没有必要,只是无缘无故地使事情复杂化。谢谢你的输入。我不知道,我是ways认为它们都是相同的级别…PS:我的程序不会再崩溃。但是,它的输出对于大小写来说是错误的。它打印的不是“无效”,而是“有效”:(((.When:堆栈为空,有一个右括号,并且堆栈中还有一些字符string@user你看过我的答案了吗?建议就在最后一句。我不会告诉你到底要把哪个字母放在哪里,这毕竟是家庭作业:)我只是不知道如何在迭代仍在进行时退出for循环,并将值保持为false…无论如何,感谢您的帮助。我将尽最大努力找出PS:我尝试放置“break”;但它不起作用:((我想我必须尝试一下,这是完全错误的。这取决于你想从中得到什么。在无效的东西可以重新变为有效的情况下,你不想
返回false
。在你的情况下,你肯定不想
在循环中返回true
。阅读
返回的内容,
继续
break
这样做,您将了解它们是如何工作的。谢谢您的回答。但是,我们还没有学习vector,也不能使用堆栈头文件:(,但我会记住这一点,作为将来的建议;)vector只用于我的测试用例,它不是解决方案的一部分
#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; } }
}