我遇到了这个问题: 用户编写数学表达式,程序需要从中提取内部()ex的所有子表达式。 (x + 2)或(x +(y-2))。
例如,如果用户输入2-(5 +(x-6) - (y + 9)),程序应返回(x-6),(y + 9),(5 +(x-) 6) - (Y + 9))
这是我试过的。
#include<stdio.h>
int main()
{
char a[100];
int i=0,t,j=0;
printf("enter math expression:\n");
while( (a[i++]=getchar()) != '\n' && i < 100);
a[i] = '\0';
for (i=0; a[i]!='\0'; i++)
{
if (a[i]=='(')
{ printf("found (\n");
j++;
while (a[i] !=')')
printf("%c",a[i++]);
printf("%c",a[i]);
答案 0 :(得分:1)
由于您正在处理嵌套表达式,因此需要保留堆栈以匹配括号。理想情况下,你应该在循环内:
示例(x + (y+2))
:
i == 0 -> '(' -> s.push(0);
i == 1 -> 'x'
i == 2 -> '+'
i == 3 -> '(' -> s.push(3);
i == 4 -> 'y'
i == 5 -> '+'
i == 6 -> '2'
i == 7 -> ')' -> s.pop() [3, 7] contains '(y + 2)'
i == 8 -> ')' -> s.pop() [0, 8] contains '(x + (y+2))'
答案 1 :(得分:0)
在此上下文中,s
为cstring。
由于在有效的数学表达式中,括号是平衡的,我们可以观察到,
在#1的情况下,我们不关心第一个角色。所以,我们可以设置s = s + 1并重新开始。 在#2的情况下,我们必须找到第一个字符的匹配结束。所以,我们把它分成两部分。匹配的表达式和尾部。两者都是有效的表达。所以,我们重新开始。
int main()
{
char s[] = "2-(5+(x-6)-(y+9))";// s have to be modifiable.
extractAndPrint(s, 0); // we are at start and 0 indicates balanced
return 0;
}
现在,
void extractAndPrint(char *s, int found)
{
if(s[0] == 0) return;//no more honey
if(!found){ //so far balanced
if(s[0] == '(') extractAndPrint(s+1, 1);// case 2
else extractAndPrint(s+1, 0); //this is the case 1
} else {//start of a expression
char *t;
//separates the end of current expression
//and the remaining part.
mark_end(s, 0, &t);
printf("(%s)\n", s);
extractAndPrint(s, 0);//potentially contain more expression
extractAndPrint(t, 0);//check past the previous exp
}
}
我也喜欢这里的递归。它对我的思考少了。可以更优雅的方式实施。
void mark_end(char *s, int c, char **t)
{
if(c == 0){
if(s[0] == ')'){
*t = s+1;
*s = '\0';
} else if(s[0] == '('){
mark_end(s+1, c+1, t);
} else {
mark_end(s+1, c, t);
}
} else {
if(s[0] == ')'){
mark_end(s+1, c-1, t);
} else if(s[0] == '('){
mark_end(s+1, c+1, t);
} else {
mark_end(s+1, c, t);
}
}
}
输出:
(5+(x-6)-(y+9))
(x-6)
(y+9)
答案 2 :(得分:0)
答案 3 :(得分:0)
您应该使用递归将字符串解析为括号树。以下示例说明如何执行此操作:
#include <stdio.h>
#include <string.h>
#define MAX_DATA 100
int mathexp(const char *exp, int start, int end)
{
int i = start;
while(i < (start + end) && exp[i] != ')') {
if(exp[i] == '(') {
i = mathexp(exp, i + 1, end) + 1;
} else {
i++;
}
}
char subexp[i - start];
memcpy(subexp, &exp[start], i - start);
subexp[i - start] = '\0';
printf("%s\n", subexp);
return i;
}
int main(int argc, char *argv[])
{
char input[MAX_DATA];
printf("Enter a math expression: ");
fgets(input, sizeof(input), stdin);
input[strcspn(input, "\r\n")] = '\0'; // remove trailing \r\n
mathexp(input, 0, strlen(input));
return 0;
}
当你测试它时,你有:
Enter a math expression: 2-(5+(x-6)-(y+9))
x-6
y+9
5+(x-6)-(y+9)
2-(5+(x-6)-(y+9))