第 8 章 KNK C 编程(数组和布尔值)中重复数字工作示例的替代解决方案
Alternative Solution to repeated digit worked example in chapter 8, KNK C Programming (Arrays & Boolean Values)
我正在尝试解决 KNK 的 C 编程,一种现代方法中第 8 章的已解决问题。我理解他们提出的答案,但想知道为什么我的答案是错误的。我难住了...
我正在尝试使用数组和 getchar() 函数编写一个程序来读取一个正数并检查它是否有重复的数字。
我的程序使用布尔值来跟踪数字中出现的数字。名为 digit_seen
的数组的索引从 0 到 9 对应于 10 个可能的数字。最初数组的每个元素都是 false
.
我会喜欢编写一个程序,当给定一个数字 n 时,从左到右一次检查 n 的一个数字。将每个检查的数字存储到 digit
变量中,然后将其用作 digit_seen
的索引。如果 digit_seen[digit]
为真,则 digit
在 n 中至少出现两次。但是,如果 digit_seen[digit]
为假,则 digit
之前未曾见过,程序随后会将 digit_seen[digit]
更新为真并继续。
这是我不完善的代码:
#include <stdbool.h>
#include <stdio.h>
int main()
{
bool digit_seen[10] = {false};
int digit;
printf("Enter a positive number: ");
while((digit = getchar()) != EOF) {
if(digit_seen[digit])
break;
digit_seen[digit] = true;
}
if(digit == EOF)
printf("No repeated digit\n");
else
printf("Repeated digit\n");
}
让我简要解释一下为什么我(显然错误地)认为它应该有效。假设我输入数字 12(即 n=12)。然后getchar()
取1,放入digit
。注意 1 != EOF,所以执行了 while 循环。我们还看到 digit_seen[digit]
是假的,所以 if 语句永远不会执行,现在我们将 digit_seen[digit]
赋值给真(即数字 1 现在已经是 'seen')。
对下一个数字 2 重复确切的过程。然后扫描所有可能的数字,我们到达 EOF。所以我们分配 digit = EOF。此时while循环还没有执行。我们转到 while 循环后面的 if 语句,看到它确实为真并打印“No repeated digit”字样。
现在假设我输入数字 22 而不是 12(即 n=22)。当我们第二次读取 2 位时 digit_seen[digit]
已经
是的,所以我们跳出了 while 循环。然后我们遇到 if(digit == EOF)
并注意到在我们 打破 的情况下 while 循环(而不是 while 括号中的参数为 false)digit
必须分别具有介于 0 和 9 之间的整数值。然而 EOF 在计算机上存储为 -1。所以 if(digit == EOF)
没有执行,而是执行了 else 子句,我们让程序正确地告诉我们输入了“重复数字”。
有人可以告诉我我在这里缺少什么吗?我的输出总是只是“重复数字”?此外,我想补充一点,这是一个有效的示例,KNK 提供了一个解决方案,但该解决方案不涉及 getchar()。它涉及 scanf() 然后使用模 (%) 和除 (/) 操作从右到左分析数字的数字。我了解他们的解决方案,但我不满足于了解他们的替代方法并且看不到我失败的地方。我觉得很好奇他们没有使用 getchar() 因为这是我在查看他们的解决方案之前的第一直觉。有没有一种方法可以使用我提出的方法通过在输入时分析 n 的数字来解决问题?还是需要像书中那样的不同方法?
作为一个没有其他人问这些问题的自学成才的程序员,任何解释都是非常慷慨的。
答案:
在考虑了您的考虑后,我发布了我的“备选答案”。只需要一个小的调整。我现在 额外 了解 getchar() 的作用和 ASCII Table。并不是说我有充分的理由不去。我会敦促任何阅读的人与 KNK 进行比较,他们应该是好奇。
#include <stdbool.h>
#include <stdio.h>
int main()
{
bool digit_seen[10] = {false};
int digit;
printf("Enter a positive number: ");
while((digit = getchar()) != '\n') {
digit -= '0';
if(digit_seen[digit])
break;
digit_seen[digit] = true;
}
if(digit == '\n')
printf("No repeated digit\n");
else
printf("Repeated digit\n");
}
getchar()
不是 return 一个数字。 return是一个字符的代码。
在 C 实现中最常用于字符的代码 ASCII 中,数字字符“0”到“9”的代码是 48 到 57。然后 digit_seen[digit]
尝试使用超出数组范围的索引。这可能会导致访问包含一些不相关值的内存的某些部分。如果该值不为零,则 digit_seen[digit]
评估为真,并执行 break;
以离开循环。
则digit == EOF
不成立,打印“重复数字”
首先,在getchar
中得到一个字符后,使用<ctype.h>
中声明的isdigit
函数测试它是否为数字字符。如果是数字字符,使用digit -= '0';
将其转换为数字(0-9)。然后你可以将它用作数组的索引。
如果不是数字字符,您可以忽略它或向用户打印警告。例如,“white space”字符(使用 isspace
函数检测)可能会被忽略。这包括当用户按下 enter 或 return.
时生成的换行符
我正在尝试解决 KNK 的 C 编程,一种现代方法中第 8 章的已解决问题。我理解他们提出的答案,但想知道为什么我的答案是错误的。我难住了...
我正在尝试使用数组和 getchar() 函数编写一个程序来读取一个正数并检查它是否有重复的数字。
我的程序使用布尔值来跟踪数字中出现的数字。名为 digit_seen
的数组的索引从 0 到 9 对应于 10 个可能的数字。最初数组的每个元素都是 false
.
我会喜欢编写一个程序,当给定一个数字 n 时,从左到右一次检查 n 的一个数字。将每个检查的数字存储到 digit
变量中,然后将其用作 digit_seen
的索引。如果 digit_seen[digit]
为真,则 digit
在 n 中至少出现两次。但是,如果 digit_seen[digit]
为假,则 digit
之前未曾见过,程序随后会将 digit_seen[digit]
更新为真并继续。
这是我不完善的代码:
#include <stdbool.h>
#include <stdio.h>
int main()
{
bool digit_seen[10] = {false};
int digit;
printf("Enter a positive number: ");
while((digit = getchar()) != EOF) {
if(digit_seen[digit])
break;
digit_seen[digit] = true;
}
if(digit == EOF)
printf("No repeated digit\n");
else
printf("Repeated digit\n");
}
让我简要解释一下为什么我(显然错误地)认为它应该有效。假设我输入数字 12(即 n=12)。然后getchar()
取1,放入digit
。注意 1 != EOF,所以执行了 while 循环。我们还看到 digit_seen[digit]
是假的,所以 if 语句永远不会执行,现在我们将 digit_seen[digit]
赋值给真(即数字 1 现在已经是 'seen')。
对下一个数字 2 重复确切的过程。然后扫描所有可能的数字,我们到达 EOF。所以我们分配 digit = EOF。此时while循环还没有执行。我们转到 while 循环后面的 if 语句,看到它确实为真并打印“No repeated digit”字样。
现在假设我输入数字 22 而不是 12(即 n=22)。当我们第二次读取 2 位时 digit_seen[digit]
已经
是的,所以我们跳出了 while 循环。然后我们遇到 if(digit == EOF)
并注意到在我们 打破 的情况下 while 循环(而不是 while 括号中的参数为 false)digit
必须分别具有介于 0 和 9 之间的整数值。然而 EOF 在计算机上存储为 -1。所以 if(digit == EOF)
没有执行,而是执行了 else 子句,我们让程序正确地告诉我们输入了“重复数字”。
有人可以告诉我我在这里缺少什么吗?我的输出总是只是“重复数字”?此外,我想补充一点,这是一个有效的示例,KNK 提供了一个解决方案,但该解决方案不涉及 getchar()。它涉及 scanf() 然后使用模 (%) 和除 (/) 操作从右到左分析数字的数字。我了解他们的解决方案,但我不满足于了解他们的替代方法并且看不到我失败的地方。我觉得很好奇他们没有使用 getchar() 因为这是我在查看他们的解决方案之前的第一直觉。有没有一种方法可以使用我提出的方法通过在输入时分析 n 的数字来解决问题?还是需要像书中那样的不同方法?
作为一个没有其他人问这些问题的自学成才的程序员,任何解释都是非常慷慨的。
答案:
在考虑了您的考虑后,我发布了我的“备选答案”。只需要一个小的调整。我现在 额外 了解 getchar() 的作用和 ASCII Table。并不是说我有充分的理由不去。我会敦促任何阅读的人与 KNK 进行比较,他们应该是好奇。
#include <stdbool.h>
#include <stdio.h>
int main()
{
bool digit_seen[10] = {false};
int digit;
printf("Enter a positive number: ");
while((digit = getchar()) != '\n') {
digit -= '0';
if(digit_seen[digit])
break;
digit_seen[digit] = true;
}
if(digit == '\n')
printf("No repeated digit\n");
else
printf("Repeated digit\n");
}
getchar()
不是 return 一个数字。 return是一个字符的代码。
在 C 实现中最常用于字符的代码 ASCII 中,数字字符“0”到“9”的代码是 48 到 57。然后 digit_seen[digit]
尝试使用超出数组范围的索引。这可能会导致访问包含一些不相关值的内存的某些部分。如果该值不为零,则 digit_seen[digit]
评估为真,并执行 break;
以离开循环。
则digit == EOF
不成立,打印“重复数字”
首先,在getchar
中得到一个字符后,使用<ctype.h>
中声明的isdigit
函数测试它是否为数字字符。如果是数字字符,使用digit -= '0';
将其转换为数字(0-9)。然后你可以将它用作数组的索引。
如果不是数字字符,您可以忽略它或向用户打印警告。例如,“white space”字符(使用 isspace
函数检测)可能会被忽略。这包括当用户按下 enter 或 return.