else if (state == OUT) 在 C 字数统计中的作用
Role of else if (state == OUT) in C word count
我正在按照《The C Programming Language》- K&R 一书学习 C;
我发现自己卡在了对else if (state == OUT)
:
的作用的理解上
#define IN 1
#define OUT 0
main ()
{
int c, nw, state;
state = OUT;
nw = 0;
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
}
printf ("%d", nw);
}
在字数统计程序中,我的意思是,在我阅读它的方式中,一定有我做错的地方,因为我无法理解为什么这会产生差异,从简单的 else
,因为 state = OUT
已经是默认条件;但实际上我观察到它确实如此,因为如果我只写 else
那么语句 state = IN; ++nw
将计算字符而不是单词;
从我的阅读方式来看,循环是说对于每个输入字符(存储在变量 c 中),如果它是一个 space、一个换行符或一个制表符,那么它就是值为零,其他所有内容都将为 1,所以我看不出它是如何将字符分组为单词的,因为 state
在循环之前已经 OUT
,那么 else if (state == OUT)
是如何得到将字符组合成一个单词的程序?
我想了一个通宵,但我的思想和书上都找不到答案
此语句正在检查字符 (c
) 值:
if (c == ' ' || c == '\n' || c == '\t')
如果任何字符 (c
) 是 space 或换行符或制表符,则 state
值更改为 OUT
.
每当字符 (c
) not 是 space 时,此语句 else if (state == OUT)
正在检查 state
的值, 换行符或制表符。
程序假设所有单词都由 space、换行符或制表符分隔,并且至少有一个字符长。
:;,.?!
等标点字符作为单词的合法字符包含在内。
使用getchar
确保至少读取一个字符。
该程序将在检测到文件结尾字符时完成,即没有进一步的输入。
第一个不是 space、换行符或制表符的字符会增加字数。
要计算单词数,我们要增加计数,++nw
,每个单词只增加一次。
如果我们写:
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else {
state = IN;
++nw;
}
然后 ++nw
将在每次 c
不是 white-space 字符 space、换行符或制表符之一时执行。但是,通过写:
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
那么++nw
不会在我们已经在word中时执行(状态为IN
)。它只会在我们用完一个单词(状态为 OUT
)并进入一个新单词(因为 c
不是 white-space 字符之一)时执行。因此,++nw
仅在我们开始一个新单词时执行,而不是针对单词中的每个字符执行。
cccc cc c c cccccc cc
^ ^ ^ ^ ^ ^
| | | | | |
这是计算字数的两种方法 - 只有转换才算数。
从几何角度看,这很简单直观:每个 c
的左边都有一个白色的 space。
但是如果你单步(一次,盲目地)遍历每个元素,你只需要存储最后一个字符,它对应于“left”。这个最小的内存使这个算法成为一个状态机。
当你打一个字母时,如果你从一个单词的外部来,你只计算它,但同时将状态设置为内部,所以下一个字母不会被计算在内。下一个 space 然后将触发器设置为“OUT”。
此程序通过对具有两个状态的非常简单的状态机建模来计算单词数:
OUT: We have not read a character that is part of a word
IN: We have read a character that is part of a word
字数由我们从OUT
状态转换到IN
状态的次数决定。给定像 "This is a test"
这样的输出,转换的工作方式如下:
This is a test
^+++v--^+v^v----^+++
其中+
表示IN
状态,-
表示OUT
状态,^
表示从OUT
过渡到IN
,而v
表示从IN
到OUT
的过渡。字数等于我们看到的次数^
.
为了知道我们是否正在从 OUT
状态转换到 IN
状态,我们必须检查 state
的当前值,当我们看到一个非空白字符;因此,
else if (state == OUT)
作为备用分支而不是普通的 else
。否则我们会为每个非空白字符递增 nw
,而不是在从 OUT
到 IN
的过渡时递增。
我正在按照《The C Programming Language》- K&R 一书学习 C;
我发现自己卡在了对else if (state == OUT)
:
#define IN 1
#define OUT 0
main ()
{
int c, nw, state;
state = OUT;
nw = 0;
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
}
printf ("%d", nw);
}
在字数统计程序中,我的意思是,在我阅读它的方式中,一定有我做错的地方,因为我无法理解为什么这会产生差异,从简单的 else
,因为 state = OUT
已经是默认条件;但实际上我观察到它确实如此,因为如果我只写 else
那么语句 state = IN; ++nw
将计算字符而不是单词;
从我的阅读方式来看,循环是说对于每个输入字符(存储在变量 c 中),如果它是一个 space、一个换行符或一个制表符,那么它就是值为零,其他所有内容都将为 1,所以我看不出它是如何将字符分组为单词的,因为 state
在循环之前已经 OUT
,那么 else if (state == OUT)
是如何得到将字符组合成一个单词的程序?
我想了一个通宵,但我的思想和书上都找不到答案
此语句正在检查字符 (c
) 值:
if (c == ' ' || c == '\n' || c == '\t')
如果任何字符 (c
) 是 space 或换行符或制表符,则 state
值更改为 OUT
.
每当字符 (c
) not 是 space 时,此语句 else if (state == OUT)
正在检查 state
的值, 换行符或制表符。
程序假设所有单词都由 space、换行符或制表符分隔,并且至少有一个字符长。
:;,.?!
等标点字符作为单词的合法字符包含在内。
使用getchar
确保至少读取一个字符。
该程序将在检测到文件结尾字符时完成,即没有进一步的输入。
第一个不是 space、换行符或制表符的字符会增加字数。
要计算单词数,我们要增加计数,++nw
,每个单词只增加一次。
如果我们写:
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else {
state = IN;
++nw;
}
然后 ++nw
将在每次 c
不是 white-space 字符 space、换行符或制表符之一时执行。但是,通过写:
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
那么++nw
不会在我们已经在word中时执行(状态为IN
)。它只会在我们用完一个单词(状态为 OUT
)并进入一个新单词(因为 c
不是 white-space 字符之一)时执行。因此,++nw
仅在我们开始一个新单词时执行,而不是针对单词中的每个字符执行。
cccc cc c c cccccc cc
^ ^ ^ ^ ^ ^
| | | | | |
这是计算字数的两种方法 - 只有转换才算数。
从几何角度看,这很简单直观:每个 c
的左边都有一个白色的 space。
但是如果你单步(一次,盲目地)遍历每个元素,你只需要存储最后一个字符,它对应于“left”。这个最小的内存使这个算法成为一个状态机。
当你打一个字母时,如果你从一个单词的外部来,你只计算它,但同时将状态设置为内部,所以下一个字母不会被计算在内。下一个 space 然后将触发器设置为“OUT”。
此程序通过对具有两个状态的非常简单的状态机建模来计算单词数:
OUT: We have not read a character that is part of a word
IN: We have read a character that is part of a word
字数由我们从OUT
状态转换到IN
状态的次数决定。给定像 "This is a test"
这样的输出,转换的工作方式如下:
This is a test
^+++v--^+v^v----^+++
其中+
表示IN
状态,-
表示OUT
状态,^
表示从OUT
过渡到IN
,而v
表示从IN
到OUT
的过渡。字数等于我们看到的次数^
.
为了知道我们是否正在从 OUT
状态转换到 IN
状态,我们必须检查 state
的当前值,当我们看到一个非空白字符;因此,
else if (state == OUT)
作为备用分支而不是普通的 else
。否则我们会为每个非空白字符递增 nw
,而不是在从 OUT
到 IN
的过渡时递增。