Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.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
理解getchar导致的c循环_C_Arrays_Function_Char_Stdio - Fatal编程技术网

理解getchar导致的c循环

理解getchar导致的c循环,c,arrays,function,char,stdio,C,Arrays,Function,Char,Stdio,我正在为下面的程序寻求帮助,今天下午我已经为此挣扎了好几个小时 我想创建一个函数,该函数接收字符数组(属于字母表a={a,b,c})及其dim,如果字符属于语言L,则返回1,否则返回0 语言是:a^k b^n c^m,因此k,m>=0和n>0 我非常努力,我将公布我所取得的成就,但我的方法似乎非常长(除了缺乏功能) 我想知道如何改进我的代码 #include <stdio.h> int array(char v[], int dim) { int i, j, k, trovat

我正在为下面的程序寻求帮助,今天下午我已经为此挣扎了好几个小时

我想创建一个函数,该函数接收字符数组(属于字母表
a={a,b,c}
)及其dim,如果字符属于语言L,则返回1,否则返回0

语言是:
a^k b^n c^m
,因此
k,m>=0
n>0

我非常努力,我将公布我所取得的成就,但我的方法似乎非常长(除了缺乏功能)

我想知道如何改进我的代码

#include <stdio.h>
int array(char v[], int dim) {
   int i, j, k, trovato = 1;
   if (v[0] == 'c') trovato = 0;

   if (v[0] == 'a') {
      for (i = 1; i < dim; i++) {
         while (trovato == 1) {
            if (v[i] == 'c')
               trovato = 0;
            else if (v[i] == 'b') {
               trovato = 1;
               for (j = i + 1; j < dim; j++) {
                  while (trovato == 1) {
                     if (v[j] == 'a') trovato = 0;
                     if (v[j] == 'b')
                        trovato = 1;
                     else if (v[j] == 'c') {
                        trovato = 1;
                        for (k = j + 1; k < dim; k++) {
                           while (trovato == 1) {
                              if (v[k] == 'c')
                                 trovato = 1;
                              else
                                 trovato = 0;
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }

   if (v[0] == 'b') {
      for (i = 1; i < dim; i++) {
         while (trovato == 1) {
            if (v[i] == 'a') trovato = 0;
            if (v[i] == 'b')
               trovato = 1;
            else if (v[i] == 'c') {
               trovato = 1;
               for (j = i; j < dim; j++) {
                  while (trovato == 1) {
                     if (v[j] != 'c')
                        trovato = 0;
                     else
                        trovato = 1;
                  }
               }
            }
         }
      }
   }

   return trovato;
}

int main() {
   char d;
   int DIM, i = 0, k;
   scanf("%d", &DIM);
   char r[DIM];
   scanf("%c", &d);
   d = getchar();
   while (d != '\n') {
      r[i] = d;
      i++;
      scanf("%c", &d);
      d = getchar();
   }
   k = array(r, DIM);
   printf("%d\n", k);
   return 0;
}
向量数组应该如何初始化


我真正关心的是效率,我害怕不能如此快速和正确地提高,这就是为什么我要对我试图完成的工作提出严格但建设性的批评。

让我们试着让它变得更简单。我们计算一个指针,该指针超过数组的末尾(v+dim),这样我们就不需要使用索引和索引变量,而是可以修改
v
指针本身

int matches(const char *v, size_t dim) {
    const char *end = v + dim;
    size_t k = 0, m = 0, n = 0;

    // count consecutive 'a's.
    // for as long as `v` is positioned before the end
    // and points to an 'a', increment `v` and increment `k`.
    while (v < end && *v == 'a') {
        k ++;
        v ++;
    }

    // count consecutive 'b's
    while (v < end && *v == 'b') {
        m ++;
        v ++;
    }

    // count consecutive 'c's
    while (v < end && *v == 'c') {
        n ++;
        v ++;
    }

    // we didn't meet the end yet, something else was seen!
    if (v < end) {
        // not just aaa...bbbbb....cccc...
        return 0;
    }

    // there were only a's, b's, c's in that order
    else {
        check that k, m, n matches the constraints 
        and return a result based on that.
    }
}
你已经读了两遍了。您只需要
getchar()


这就是在文件或换行符结束之前读取输入所需的全部内容。

让我们尽量简化它。我们计算一个指针,该指针超过数组的末尾(v+dim),这样我们就不需要使用索引和索引变量,而是可以修改
v
指针本身

int matches(const char *v, size_t dim) {
    const char *end = v + dim;
    size_t k = 0, m = 0, n = 0;

    // count consecutive 'a's.
    // for as long as `v` is positioned before the end
    // and points to an 'a', increment `v` and increment `k`.
    while (v < end && *v == 'a') {
        k ++;
        v ++;
    }

    // count consecutive 'b's
    while (v < end && *v == 'b') {
        m ++;
        v ++;
    }

    // count consecutive 'c's
    while (v < end && *v == 'c') {
        n ++;
        v ++;
    }

    // we didn't meet the end yet, something else was seen!
    if (v < end) {
        // not just aaa...bbbbb....cccc...
        return 0;
    }

    // there were only a's, b's, c's in that order
    else {
        check that k, m, n matches the constraints 
        and return a result based on that.
    }
}
你已经读了两遍了。您只需要
getchar()


这是在文件或换行符结束前读取输入所需的全部内容。

另一种方法是使用它为您生成输入。从他们的网站上

它的主要目标是生成快速的lexer:至少和经过合理优化的手工编码的lexer一样快


您可以获得区分大小写的输出和许多其他选项,请参阅。

另一种方法是为您生成它。从他们的网站上

它的主要目标是生成快速的lexer:至少和经过合理优化的手工编码的lexer一样快


您可以获得区分大小写的输出和许多其他选项,请参阅。

@p.p.谢谢!有这样做的链接吗?这不是太复杂了吗?您只需连续计算
a
s,然后是
b
s,然后是
c
s;如果你得到了任何意想不到的东西,比如
d
a
后面没有
b
,你就可以摆脱困境;然后检查values@AnttiHaapala在输入中,我只能放一个b和c,计数的问题是,我必须从第一个元素开始,对数组的下一个元素进行计数,因为顺序计数,不是吗?如果你有一个快速的解决方案,我很高兴听到!另外,有一个工具可以将正则表达式转换为C代码,@P.P.谢谢!有这样做的链接吗?这不是太复杂了吗?您只需连续计算
a
s,然后是
b
s,然后是
c
s;如果你得到了任何意想不到的东西,比如
d
a
后面没有
b
,你就可以摆脱困境;然后检查values@AnttiHaapala在输入中,我只能放一个b和c,计数的问题是,我必须从第一个元素开始,对数组的下一个元素进行计数,因为顺序计数,不是吗?如果你有一个快速的解决方案,我很高兴听到!顺便说一句,有一个工具可以将正则表达式转换成C代码。对我来说有点太复杂了,谢谢你,但我会尽力理解它anyway@jacopoburelli这是自动生成的状态机,实际上不是人类可读的;)对我来说有点太复杂了,谢谢你,但我会尽力理解的anyway@jacopoburelli这是自动生成的状态机,实际上不是人类可读的;)
scanf("%c",&d);
d=getchar();
int c;  // getchar returns an *int*

while ((c = getchar()) != EOF && c != '\n') {
    r[i ++] = d;
}
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

static int match(const char *const s) {
    const char *t = s, *marker;
    /*!re2c
        re2c:yyfill:enable = 0;
        re2c:define:YYCTYPE = char;
        re2c:define:YYCURSOR = t;
        re2c:define:YYMARKER = marker;

        pattern = 'a'* 'b'+ 'c'*;
        end = '\n'? "\x00";
        *           { return 0; }
        pattern end { return 1; }
    */
}

int main(void) {
    char a[512];
    while(fgets(a, sizeof a, stdin))
        printf("[%s] %s", match(a) ? "passed" : "reject", a);
    if(errno) return perror("input"), EXIT_FAILURE;
    return EXIT_SUCCESS;
}
/* Generated by re2c 1.0.3 on Sun Oct 21 18:38:31 2018 */
#line 1 "a.re"
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#line 6 "a.re"


static int match(const char *const s) {
    const char *t = s, *marker;

#line 14 "<stdout>"
{
    char yych;
    yych = *t;
    switch (yych) {
    case 'A':
    case 'a':   goto yy4;
    case 'B':
    case 'b':   goto yy5;
    default:    goto yy2;
    }
yy2:
    ++t;
yy3:
#line 18 "a.re"
    { return 0; }
#line 30 "<stdout>"
yy4:
    yych = *(marker = ++t);
    switch (yych) {
    case 'A':
    case 'B':
    case 'a':
    case 'b':   goto yy7;
    default:    goto yy3;
    }
yy5:
    yych = *(marker = ++t);
    switch (yych) {
    case 0x00:
    case '\n':
    case 'B':
    case 'C':
    case 'b':
    case 'c':   goto yy10;
    default:    goto yy3;
    }
yy6:
    yych = *++t;
yy7:
    switch (yych) {
    case 'A':
    case 'a':   goto yy6;
    case 'B':
    case 'b':   goto yy9;
    default:    goto yy8;
    }
yy8:
    t = marker;
    goto yy3;
yy9:
    yych = *++t;
yy10:
    switch (yych) {
    case 0x00:  goto yy11;
    case '\n':  goto yy13;
    case 'B':
    case 'b':   goto yy9;
    case 'C':
    case 'c':   goto yy14;
    default:    goto yy8;
    }
yy11:
    ++t;
#line 19 "a.re"
    { return 1; }
#line 80 "<stdout>"
yy13:
    yych = *++t;
    if (yych <= 0x00) goto yy11;
    goto yy8;
yy14:
    yych = *++t;
    switch (yych) {
    case 0x00:  goto yy11;
    case '\n':  goto yy13;
    case 'C':
    case 'c':   goto yy14;
    default:    goto yy8;
    }
}
#line 20 "a.re"

}

int main(void) {
    char a[512];
    while(fgets(a, sizeof a, stdin))
        printf("[%s] %s", match(a) ? "passed" : "reject", a);
    if(errno) return perror("input"), EXIT_FAILURE;
    return EXIT_SUCCESS;
}