理解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;
}