我正在做一项学校作业,目前我被某个部分卡住了。
我下面展示的程序应该取7个数字,检查它们是否高于0并低于maxValue,然后,另一个函数checkIfContains应该检查该数组中是否有任何重复项,并向第一个函数enterRow返回true或false。
如果一切都很好(数字在范围内,没有重复(,那么这里的函数就不需要再做任何事情了。。(我已经隔离了这两个。还有更多这些来自哪里,我们应该做一个彩票游戏(
我做错了什么?
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
void enterRow(int numbers[], int len, int maxValue);
bool checkIfContains(int digit, int arrayToCheck[], int len);
int main(void)
{
int len = 7;
int maxValue = 39;
int numbers[len];
memset(numbers, 0, sizeof(int) * len);
enterRow(numbers, len, maxValue);
return 0;
}
void enterRow(int numbers[], int len, int maxValue)
{
int flag = 1;
printf("nEnter your lotto row (%d values between 1-%d): ", len, maxValue);
do
{
for(int i = 0; i < len; i++) scanf(" %d", &numbers[i]);
for (int i = 0; i < len; i++)
{
if (numbers[i] < 1 || numbers[i] > maxValue)
{
printf("Numbers must be between 1-%d, try again!n", maxValue);
break;
}
if (checkIfContains(numbers[i], numbers, len) == true)
{
printf("Duplicate, try again: ");
break;
}
else
{
flag = 2;
}
}
} while (flag == 1);
}
bool checkIfContains(int digit, int arrayToCheck[], int len)
{
for (int i = 1; i < len; i++)
{
if (arrayToCheck[i] == digit)
{
return true;
}
else
{
return false;
}
}
}
几个问题:
- check函数将根据自身检查当前值,因此数组将始终有重复的值
- 您只想在循环结束时返回
false
- 函数末尾没有
return
- 您的循环以1开始,但需要以0开始
要修复,而不是传递匹配值,请传递该值的索引。
以下是重构后的代码:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
void enterRow(int numbers[], int len, int maxValue);
bool checkIfContains(int curidx, int arrayToCheck[], int len);
int
main(void)
{
int len = 7;
int maxValue = 39;
int numbers[len];
memset(numbers, 0, sizeof(int) * len);
enterRow(numbers, len, maxValue);
return 0;
}
void
enterRow(int numbers[], int len, int maxValue)
{
int flag = 1;
printf("nEnter your lotto row (%d values between 1-%d): ", len, maxValue);
do {
for (int i = 0; i < len; i++)
scanf(" %d", &numbers[i]);
for (int i = 0; i < len; i++) {
if (numbers[i] < 1 || numbers[i] > maxValue) {
printf("Numbers must be between 1-%d, try again!n", maxValue);
break;
}
if (checkIfContains(i, numbers, len) == true) {
printf("Duplicate, try again: ");
break;
}
else {
flag = 2;
}
}
} while (flag == 1);
}
bool
checkIfContains(int curidx, int arrayToCheck[], int len)
{
int digit = arrayToCheck[curidx];
for (int i = 0; i < len; i++) {
// don't check number against itself
if (i == curidx)
continue;
if (arrayToCheck[i] == digit)
return true;
}
return false;
}
函数checkIfContains
有两个缺陷。
首先,循环应从作为参数数字值传递给函数的元素的下一个位置开始。这意味着函数至少应该像一样被调用
if (checkIfContains(numbers[i], numbers + i + 1, len - i - 1 ) == true)
在功能范围内,for循环应从0 开始
for (int i = 0; i < len; i++)
而不是你的函数中的1
for (int i = 1; i < len; i++)
第二个缺陷是,一旦在数组中发现不相等的元素,就不能返回false。
使用您的方法该功能可以按以下方式查看
bool checkIfContains(int digit, const int arrayToCheck[], int len)
{
int i = 0;
while ( i < len && arrayToCheck[i] != digit ) ++i;
return i != len;
}
正如我已经提到的,函数必须像一样调用
if (checkIfContains(numbers[i], numbers + i + 1, len - i - 1 ) == true)
尽管你的方法太复杂了。您可以在第一个循环中检查输入的值
for(int i = 0; i < len; i++)
{
scanf(" %d", &numbers[i]);
// 1) check whether the value is in the range
// 2) check whether the value is unique
//...
}
要检查数组中是否存在重复项,最基本的方法是使用两个嵌套的for循环遍历数组,并将每个元素与其他元素进行比较,如下所示:
int array[5] = {5, 7, 6, 3, 5};
int arrayLength = 5;
for(int i = 0; i < arrayLength; i++)
{
for(int j = i + 1; j < arrayLength; j++)
{
if(array[i] == array[j])
{
printf("%d has duplicaten", array[i]);
}
}
}
你可以让你的代码像:
bool hasDuplicate(int array[], int arrayLength)
{
for(int i = 0; i < arrayLength; i++)
{
for(int j = i + 1; j < arrayLength; j++)
{
if(array[i] == array[j])
{
return true;
}
}
}
return false;
}
你可以把enterRow
做成这样:
void enterRow(int numbers[], int len, int maxValue)
{
printf("nEnter your lotto row (%d values between 1-%d): ", len, maxValue);
for(int i = 0; i < len; i++)
scanf(" %d", &numbers[i]);
for(int i = 0; i < len; i++)
{
if(numbers[i] > maxValue || numbers[i] < 1)
{
printf("Format is not correct.n");
while(1);
}
}
if(hasDuplicate(numbers, len) == true)
{
printf("The numbers cannot be duplicates.n");
while(1);
}
}
通过这种方式,您的代码更加清晰易读。显然,您应该优化此代码,以处理错误情况等。