Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从内部提取字符';(';和';)';从C中的char数组_C_Arrays_Parsing_Char_Extract - Fatal编程技术网

从内部提取字符';(';和';)';从C中的char数组

从内部提取字符';(';和';)';从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

我被困在这个问题上: 用户编写一个数学表达式,程序需要从中提取()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]);
#包括
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

    因为在有效的数学表达式中,括号是平衡的,我们可以观察到

  • 如果s[0]不是'('
  • 如果s[0]是“(”的话,那么我们就在括号表达式的开头
  • 对于#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 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))