完全披露:这是作业。我不是在寻找明确的答案,而是寻求一点指导。
我很难在C中初始化我的堆栈。具体来说,我似乎无法正确地将新元素推入堆栈。我知道我的push / pop / etc函数是正确的(它们是提供的)但是我担心我没有正确地看待它。
这是读取字符串并确定它是否“平衡”的基本尝试(所有括号,卷曲和方括号都有合作伙伴并以正确的顺序显示。)据我所知,它不是我的逻辑问题,我相信语法是正确的,所以我有点不知所措......
以下是我对实施的尝试:
int isBalanced(char* s) {
struct DynArr *string;
string = newDynArr(50);
while (nextChar(s) != '\0') {
if ((nextChar(s) == '(') || (nextChar(s) == '{') || (nextChar(s) == '[')) {
pushDynArr(string, nextChar(s));
}
if (nextChar(s) == ')') {
if (topDynArr(string) != '(') {
return 0;
} else popDynArr(string);
}
if (nextChar(s) == '}') {
if (topDynArr(string) != '{') {
return 0;
} else popDynArr(string);
}
if (nextChar(s) == ']') {
if (topDynArr(string) != '[') {
return 0;
} else popDynArr(string);
}
}
if (isEmptyDynArr(string)) {
printf("The stack is empty\n");
return 1;
} else return 0;
}
输出始终打印“堆栈为空”并返回true,尽管我给它提供了不平衡的字符串。我可能已经看了太长时间并且无法识别这一点。我很感激您可以借出的任何帮助。我不需要明确的答案,但推动正确的方向就足够了。
编辑:以下是已请求的功能......
int isEmptyDynArr(DynArr *v)
{
if(v->size == 0) {
return 1;
}
else return 0;
}
DynArr* newDynArr(int cap)
{
assert(cap > 0);
DynArr *r = (DynArr *)malloc(sizeof( DynArr));
assert(r != 0);
initDynArr(r,cap);
return r;
}
void pushDynArr(DynArr *v, TYPE val)
{
assert(v != 0);
addDynArr(v, val);
}
void popDynArr(DynArr *v)
{
assert(v != 0);
assert(isEmptyDynArr(v) == 0);
v->size--;
}
TYPE topDynArr(DynArr *v)
{
assert(v != 0);
assert(isEmptyDynArr(v) == 0);
return v->data[v->size - 1];
}
char nextChar(char* s)
{
static int i = -1;
char c;
++i;
c = *(s+i);
if ( c == '\0' )
return '\0';
else
return c;
}
答案 0 :(得分:2)
此行可能会从输入行跳过1或2或3个字符:
nextChar(s) == '(') || (nextChar(s) == '{') || (nextChar(s) == '['
你最应该使用:
char ch = nextChar(s);
if( ch == '(' || ch == '{' || c == '[' )
答案 1 :(得分:1)
您似乎无法在任何地方递增s
。你的nextChar
函数有什么作用?我只能猜测,但它似乎只会返回*s
。如果是这种情况,则需要在每次迭代后递增s(++s
)。如果它 神奇地(因为在普通C中确实没有明智的方法),无论如何都要增加s,你应该每次迭代只调用一次并保存结果。我猜它是前者,在这种情况下例如这个字符串:“(())”你将读取第一个'('两次并返回0。
更新:是的,显然你的nextChar函数 使用全局计数器。建议二适用,每次迭代只调用一次。或者更好的是,摆脱那件事。设计函数的方式,您可以在程序的整个生命周期中有效地使用它一次,并且该事物的整个功能可以替换为(* s?*(s ++):* s)。或者只是*(s ++)(并且自己检查0)。