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