簡體   English   中英

使用 C 確定字符串是否包含任何不平衡的括號

[英]Using C to determine if a string contains any imbalanced brackets

我正在完成一些課程作業並陷入最后的障礙,我需要確定字符串是否包含任何括號不平衡。 但我只能使用 C。我讀到這是一些組織使用的非常流行的面試問題,我有一個解決方案,但我知道它是不正確的。 答案需要使用堆棧來壓入和彈出變量? 有人有建議嗎。 我為我的天真感到抱歉。

這是我的解決方案:

int balanced(char line [LINE_LENGTH])
{
    int bracketCount = 0;
        
    for (int counter = 0 ; counter < strlen(line) ; counter++)
    {
        if (line[counter] == '[' || line[counter] == ']' || line[counter] == '(' || line[counter] == ')' || line[counter] == '{' || line[counter] == '}')
        { 
            bracketCount++;
        }
    }
    return bracketCount;
}

您的解決方案是不正確的:您為兩種類型的括號增加了bracketCount ,因此 function 只返回括號總數,它不檢查適當的平衡。

您可以通過增加左括號的bracketCount並在右括號上減少它來改進您的方法:這會檢測到缺少的括號,但不會檢測到不平衡或不匹配的括號。

您可以為{[(使用不同的計數器,並分別跟蹤括號類型,但您仍然不會像"([)]"那樣檢測嵌套錯誤

要實現正確的檢查器,您需要將左括號存儲在一個堆棧中,您可以在其中檢查每個右括號是否與當前打開的括號匹配。

這是一個使用char數組作為堆棧的簡單實現:

int balanced(const char *line) {
    char brackets[LINE_LENGTH];
    char *bp = brackets + LINE_LENGTH;

    *--bp = '\0';
    for (size_t i = 0; line[i] != '\0'; i++) {
        char cc;
        switch (line[i]) {
          case '[':
            cc = ']';
            break;
          case '(':
            cc = ')';
            break;
          case '{':
            cc = '}';
            break;
          case ']':
          case ')':
          case '}':
            if (*bp == '\0') {
                /* stack is empty: unexpected closing bracket */
                printf("offset %zu: no opening bracket for '%c'\n",
                       i, line[i]);
                return 0;
            }
            if (*bp != line[i]) {
                /* nesting error: closing bracket does not match the expected type */
                printf("offset %zu: bad bracket type for '%c', expected '%c'\n",
                       i, line[i], *bp);
                return 0;
            }
            bp++;
            continue;
          default:
            continue;
        }
        if (bp == brackets) {
            /* stack overflow */
            printf("too many open brackets\n");
            return -1;
        }
        *--bp = cc;  /* push the expected closing bracket */
    }
    if (*bp) {
        /* some opening brackets have not been closed */
        printf("missing brackets: %s\n", bp);
        return 0;
    }
    return 1;    
}

這是一個更簡單的遞歸方法:

#include <stdio.h>

const char *check_brace(const char str[], int endc) {
    while (str) {
        int c = *str++;
        switch (c) {
          case '(': str = check_brace(str, ')'); break;
          case '[': str = check_brace(str, ']'); break;
          case '{': str = check_brace(str, '}'); break;
          case ')':
          case ']':
          case '}':
          case '\0': return (c == endc) ? str : NULL;
        }
    }
    return NULL;
}

int balanced(const char *line) {
    return check_brace(line, '\0') != NULL;
}

int main() {
    char str[80];
    if (fgets(str, sizeof str, stdin)) {
        printf("%d\n", balanced(str, '\0') != NULL);
    }
    return 0;
}

這是一種確定一串括號是否平衡的方法。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static inline char match_bracket (const char ch) {
    switch (ch) {
    case '{' : return '}';
    case '}' : return '{';
    case '(' : return ')';
    case ')' : return '(';
    case '[' : return ']';
    case ']' : return '[';
    default:
        fprintf (stderr, "\nERROR: %c is not supported\n", ch);
        exit (1);
    }
}


/**
 * Opening Brackets : [ { (
 * Closing Brackets : ] } )
 * Balanced : No overlapping of brackets & every open has a matching close
 * Example :    {[({})]} - balanced
 *              {[(}{)]} - unbalanced
 * Function returns on first detection of any error
 */
int check_bracket_balance (const char* brkts, const int slen)
{
    if (!brkts || ! (*brkts) || slen < 0) {
        printf ("\tInvalid arguments\n");
        return -1;
    }
    const char* open_brackets = "([{";
    const char* close_brackets = ")]}";

    char bStack [slen + 1]; // array stack emulation
    int sTop = -1;
    for (int bi = 0; bi < slen; ++bi) {
        if (strchr (open_brackets, brkts[bi]))
            bStack[++sTop] = brkts[bi];                 // push on to stack
        else if (strchr (close_brackets, brkts[bi])) {  // a closing bracket
            if (sTop < 0) {  // empty Stack
                printf ("\tExpected %c before %c at %d\n", match_bracket (brkts[bi]), brkts[bi], bi + 1);
                return 1;
            }
            if (bStack[sTop] == match_bracket (brkts[bi])) // is stack-top a matching bracket
                --sTop;     // pop matching bracket from stack
            else {
                printf ("\tExpected %c before %c at %d\n", match_bracket (bStack[sTop]), brkts[bi], bi + 1);
                return 2;
            }
        } else {
            printf ("\tInvalid char %c at %d\n", brkts[bi], bi + 1);
            return -2;  // use enums like eInvBracketChar for easier code-read
        }
    }
    if (sTop >= 0) {
        printf ("\tThere are %d unmatched opening brackets\n", sTop + 1);
        return 3;
    }
    return 0; // balanced
}


#define MAX_STRINGS 8
int main ()
{
    char* strings[MAX_STRINGS] = {"{([])}",
        "{}()[]",
        "{})([]",
        "{([)]}",
        "{{(([[",
        "",
        "{}<>{}",   // assuming <> are invalid
        "Testing"
    };
    printf ("\n");
    for (int si =0; si < MAX_STRINGS; ++si) {
        printf ("\n%s\n", strings[si]);
        int error = check_bracket_balance (strings[si], strlen (strings[si]));
        if (error)
            printf ("\tERROR[%d]: Brackets not Balanced\n", error);
        else
            printf ("\tBrackets Balanced\n");
    }

    printf ("\n");
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM