从内部提取字符';(';和';)';从C中的char数组
我被困在这个问题上: 用户编写一个数学表达式,程序需要从中提取()ex.(x+2)或(x+(y-2))中的所有子表达式从内部提取字符';(';和';)';从C中的char数组,c,arrays,parsing,char,extract,C,Arrays,Parsing,Char,Extract,我被困在这个问题上: 用户编写一个数学表达式,程序需要从中提取()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"); w
例如,如果用户输入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]);
#包括
int main()
{
chara[100];
int i=0,t,j=0;
printf(“输入数学表达式:\n”);
而((a[i++]=getchar())!='\n'&&i<100);
a[i]='\0';
对于(i=0;a[i]!='\0';i++)
{
如果(a[i]=='(')
{printf(“找到(\n”);
j++;
而(a[i]!='))
printf(“%c”,a[i++]);
printf(“%c”,a[i]);
由于您处理的是嵌套表达式,因此需要保留一个堆栈来匹配括号。理想情况下,在循环内部,您应该:
(x+(y+2))
:
在此上下文中,让,
s
成为cstring
因为在有效的数学表达式中,括号是平衡的,我们可以观察到
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 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)
我建议您使用状态机,在您的情况下,此状态机应适用于:
因此,main将是一种开关类型,注意编写pop和push函数,并用良好的结构表示堆。您应该使用递归将字符串解析为括号树。下面是一个示例,演示如何执行此操作:
#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;
}
很好。如果遇到问题,只需问一个问题。不要忘了提供一个具体的问题描述以及一个。您可能还需要阅读。您在
循环中增加i
,而循环。因此,如果存在,您的程序将跳过任何其他(
在找到第一个之前)
,无法返回。只是想一想。@Mihai是否有可能跳过一些)
?我的意思不是在第一次出现)
时停止打印字符,而是在第二次出现时停止打印字符作为响应,但是像(x+(y-2))
第一次(
将匹配第一次)
这是错误的,我在上面的回答中添加了一个例子,非常感谢。推送和弹出对我来说是一个新事物,我将进一步用谷歌搜索它。堆栈有两个主要功能->
(5+(x-6)-(y+9))
(x-6)
(y+9)
#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))