我制作了一个删除括号内字符的程序。输入的文本应该具有匹配的开括号和右括号。
案例1:
输入:(Hello) World
输出:World
案例2:
输入:(Hello World
输出:(Hello World
案例3:
输入:Hello)(World
输出:Hello)(World
案例4:
输入:Hello((hi) World)
输出:Hello
案例5:
输入:(Hello) hi (World)
输出:hi
这是我的代码:
#include <stdio.h>
int main(){
char string[100] = {0};
char removedletters[100] = {0};
fgets(string, 100, stdin);
char *p;
int x = 0;
int b = 0;
for (p=string; *p!=0; p++) {
if (*(p-1) == '(' && x) {
x = 0;
}
if (*p == ')') {
x = 1;
}
if (!x){
removedletters[b] = *p;
b++;
}
}
puts(removedletters);
}
案例1,3和5是正确的,但不是案例2和案例4。 我的代码出了什么问题?
答案 0 :(得分:2)
您正在调用未定义的行为:
for(p=string; *p!=0; p++){
if(*(p-1) == '(' && x){
x = 0;
}
第一次评估p++
是在循环块的末尾,因此,*(p-1)
第一次指向string
的左边,即你正在做*(string-1)
。
不幸的是,如果您有未定义的行为,您将失去任何保修。
答案 1 :(得分:1)
我不确定该代码有什么特别的错误,但为了提高效率,我会保留最后找到的(
个字符的堆栈,并在找到)
时使用它来删除部分
半伪代码:
// str is the input string, set up to and from pointers.
stacktype stack = empty-stack
char *from = str
char *to = str
// Process every character once and once only.
while *from != '\0':
switch *from:
// Open, transfer character and store position on stack.
case '(':
*to++ = *from++
stack.push (to - 1)
break
// Close, get most recent '(' and adjust to for overwrite.
// If no most recent, just transfer as is.
case ')':
if stack is not empty:
to = stack.pop()
else:
*to++ = *from++
break
// Anything else, just transfer.
default:
*to++ = *from++
// Terminate string at truncated position.
*to = '\0'
这将逐个字符串,逐字符号,记住堆栈中的所有(
位置,但仍会传输字符。
每当您找到)
字符时,都会调整to
指针,以便从最新的(
字符开始覆盖,有效删除内部的所有内容,包括(...)
}。section。