2012-11-27 118 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)