2012-11-27 77 views
1

完全披露:这是用于转让的。我不是在寻找明确的答案,而是寻求一点指导。在执行堆栈时遇到问题

我很难用C初始化我的堆栈。具体来说,我似乎无法得到它来正确地将新元素推入堆栈。我知道我的推/流行/等功能是正确的(他们提供了),但我担心我没有正确看待这个。

这是读取字符串并确定它是否“平衡”的基本尝试(所有圆括号,卷曲和方括号都有合作伙伴并以正确顺序出现)。据我所知,它不是我的逻辑有问题,我相信语法是正确的,所以我在对思想的损失是一种...

这是我在尝试执行:

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

只是一个友好的提示:在C++中,变量与保留字/标准类具有相同的名称,因为它不是C++,但它可以更容易地移植到C++或com用C++编译器编译(由于更严格的类型规则而被视为完成)。 –

+0

显示'isEmptyDynArr()'的代码 – Omkant

+2

nextChar做什么?我在问,因为你似乎没有在任何地方递增指针。如果你这样做有nextChar - 这是不可能在C,除非你使用某种形式的全球反的,但不是在C++ - 你会碰上麻烦,因为你确定字符之前调用nextChar多次在一排。如果没有,你需要在每次迭代后增加它。 – Cubic

回答

2

这条线可以从输入线跳过1个或2或3个字符的功能...:最肯定

nextChar(s) == '(') || (nextChar(s) == '{') || (nextChar(s) == '[' 

你应该使用:

char ch = nextChar(s); 
if(ch == '(' || ch == '{' || c == '[') 
+0

另一种说法是'nextChar()'*不*幂等:每个调用都会*移动*它在字符串中的位置阅读。 – unwind

+0

@lenik谢谢你,那就是问题所在。我认为我太累了,没有意识到在对它进行任何操作之前,nextChar()的每次连续调用都在堆栈中递增。添加'char ch = nextChar(s)'允许在while循环中的每个遍中使用一个元素,其余的很好。再次感谢你。 – idigyourpast

+0

@idigyourpast不用客气 – lenik

1

你似乎没有在任何地方递增s。你的nextChar功能是做什么的?我只能猜测,但它似乎只会返回*s。如果是这种情况,则需要在每次迭代后递增s(++s)。如果它神奇地(因为在纯C中确实没有明智的做法)增加s,你应该只在每次迭代时调用它一次并保存结果确实是。我想这是前者,在这种情况下,例如对于此字符串:“(())”您将读取第一个'('两次并返回0.

更新:是的,显然你的nextChar函数确实使用一个全局计数器,建议二适用,每次迭代只调用一次,或者更好的是,摆脱那个东西。函数的设计方式,你可以在程序的整个生命周期中有效地使用它一次,并且(* s?*(s ++):* s)或者只是*(s ++)(并且只是自己检查0)