在过go 的两个小时里,我一直在调试我的代码,以判断输入是否包含格式良好的括号.我所说的"格式良好"是指()()[]([()])是可以接受的,但((((()不是.

我不允许使用除<stdio.h>以外的任何头文件

#include <stdio.h>

void cross(char str[], int i, int j) {
    str[i] = 'X';
    str[j] = 'X';
}

int iscrossed(char str[]) { 
    int i = 0;
    while (str[i] != '\0') {
        if (str[i] != 'X')
            return 0;
        i++;
    }
    return 1;
}

int check(char str[]) {
    int i = 1, j;
    while (str[i] != '\0') {
        if (str[i] == ')') {
            for (j = i - 1; j >= 0; j--) {
                if (str[j] == '(') {
                    cross(str, str[i], str[j]);
                }
                break;
            }
        } else
        if (str[i] == ']') {
            for (j = i - 1; j >= 0; j--) {
                if (str[j] == '[') {
                    cross(str, str[i], str[j]);
                }
                break;
            }
        }
        i++;
    }
    if (iscrossed(str) == 1)
        return 1;
    else
        return 0;
}

int main() {
    char str[20];
    scanf("%s", str);
    printf("%d\n", check(str));
}

对于某些输入,程序打印一个零,然后是一个分段错误,对于其他输入,它只打印一个零.

如果你的答案告诉我my代码中的错误那就太好了,因为这是我首先要问的问题.

推荐答案

代码中存在多个问题:

  • 当找到括号和方括号的匹配项时,可以调用cross(str, str[i], str[j]);而不是cross(str, i, j);.
  • break语句应该移到if块内.
  • 您的方法不允许检测嵌套错误
  • 如果str是空字符串(不能通过scanf()输入),则方法将具有未定义的行为

以下是一个修改版本:

#include <stdio.h>

void cross(char str[], int i, int j) {
    str[i] = str[j] = 'X';
}

int iscrossed(char str[]) { 
    int i = 0;
    while (str[i] != '\0') {
        if (str[i] != 'X')
            return 0;
        i++;
    }
    return 1;
}

int check(char str[]) {
    int i = 0, j;
    while (str[i] != '\0') {
        if (str[i] == ')') {
            for (j = i - 1; j >= 0; j--) {
                if (str[j] == '(') {
                    cross(str, i, j);
                    break;
                }
            }
        } else
        if (str[i] == ']') {
            for (j = i - 1; j >= 0; j--) {
                if (str[j] == '[') {
                    cross(str, i, j);
                    break;
                }
            }
        }
        i++;
    }
    return iscrossed(str);
}

int main() {
    char str[80];
    if (scanf("%79s", str) == 1) {
        printf("%d\n", check(str));
    }
    return 0;
}

这里有一个更简单的 Select :

#include <stdio.h>

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

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

C相关问答推荐

为什么 memcpy() 随机不复制正确的值?

为什么启用优化时 GCC 11 编译器会产生奇怪的输出?

Gnuplot 和 C - 绘制不同的符号/ colored颜色

在 C 中使用数组而不是向量

幂函数给出的答案与 C 中的 math.pow 函数不同

确定在嵌入式 C 中运行时使用哪个变量

在编译时构建静态数组

判断由大括号组成的输入字符串是否格式正确

通过默认网关地址的硬件地址而不是以太网多播地址发送多播

为什么 malloc() 被认为是库调用而不是系统调用?

为什么使用 MOV 指令将 XOR 交换优化为普通交换?