我之前发布了关于我的C程序中的运行时错误但现在我遇到了代码的另一个问题。我的程序运行正常,没有任何错误,但无论输入什么,它总是打印0。我花了最后4个小时试图找出我的代码为什么这样做,但我没有运气。如果有人能帮助我,我真的很感激。
我的程序接受一个整数序列的输入,使用另一个像scanf一样工作的程序。 Getint()读取整数序列的输入,并在达到EOF(-1)时停止读取输入。序列中的整数数量为1000。
// ar_max(a[]) returns the max entry of a
int ar_max(int a[]) {
int max_so_far = a[0];
for (int i = 1; i < 1000; i++) {
if (a[i] > max_so_far) {
max_so_far = a[i];
}
}
return max_so_far;
}
int main() {
int inputnum = getint();
// array containing the distinct numbers seen
int a_num[1000] = {};
// array containing the frequencies of the distinct numbers seen
int a_freq[1000] = {};
int len_n = 0;
while (inputnum != EOF) {
int i = 0;
len_n = i + 1;
int len_f = len_n;
// update the frequency of inputnum if it's already been seen
for (i = 0; i < len_f; i++, len_n += 1) {
if (a_num[i] == inputnum) {
a_freq[i] = a_freq[i] + 1;
}
}
// add inputnum into the array if it hasn't already been seen
if (i == len_n) {
a_num[i+1] = inputnum;
a_freq[i+1] = 1;
}
inputnum = getint();
}
// print the first number with the highest frequency
for (int j = 0; j < len_n; j++) {
if (a_freq[j] == ar_max(a_freq)) {
printf("%d\n", a_num[j]);
break;
}
}
}
例如,输入
10 20 30 20
应该导致20
答案 0 :(得分:1)
代码有正确的想法,但它仍然存在一些问题。
首先,您有两个包含相关信息的数组。您为每个阵列保留两个长度,并尝试保持长度相同。那很复杂。相反,请考虑为两个阵列只有一个长度。
当您在oder中循环遍历数组以检查给定数字是否已包含在数组中时:
for (i = 0; i < len_f; i++, len_n += 1) {
if (a_num[i] == inputnum) {
a_freq[i] = a_freq[i] + 1;
}
}
每次迭代时都会更新数字数组的长度。你不应该,因为你在迭代循环时没有改变任何东西的长度。
接下来,检查是否找不到该号码:
if (i == len_n) ...
这不起作用,因为你在第一个循环中更新了频率,但是没有终止循环;你的病情总是如此。您可以通过在找到号码时使用break
明确地突破循环来解决此问题。 (更好的是,使查找和频率更新一个函数,其返回值指示元素是否被找到,如果不是,则添加元素。)
追加新元素时:
if (i == len_n) {
a_num[i+1] = inputnum;
a_freq[i+1] = 1;
}
当然,你应该增加你追加的数组的长度。通常,将项附加到数组如下所示:
array[len++] = item;
回想一下,第一个索引为零,实际长度超出有效索引。
还有其他一点:
添加元素时,应确保不会溢出数组。 1000的维度是慷慨的,但不是无限的。
在函数ar_max
中,迭代数组的所有1000个元素。您已将数组初始化为零,因此最大值仍然是正确的,但最好将数组大小传递给函数,以便您只能迭代实际项目。
如果函数ar_max
返回索引而不是值,则可以使用该索引访问两个数组,并且不需要最后一个循环j
,因为{{1}只是那个索引。
如果您有两个并行数组,最好创建一个包含项目和频率的结构,并始终将它们保持在一起。这简化了代码,因为您不必保持任何同步。这样的数据布局也有助于对其他常见操作进行排序和过滤。
这是一个实现上述修复的版本。它还使用函数按值查找元素,并使j
返回数组索引而不是值。
ar_max
答案 1 :(得分:0)
int main()
{
// array containing the distinct numbers seen
int a_num[1000] = {0};
// array containing the frequencies of the distinct numbers seen
int a_freq[1000] = {0};
int len_n = 0;
int i = 0, j = 0;
// Read first entry
int inputnum = getint();
if (EOF == inputnum)
{
printf("No valid number input given\n");
return -1;
}
// Make first entry in a_num and a_freq
a_num[0] = inputnum;
a_freq[0] = 1;
// Update len_n to 1
len_n = 1;
// Get new entry from user and update number array and frequency array
inputnum = getint();
while (inputnum != EOF)
{
// update the frequency of inputnum if it's already been seen
for (i = 0; i < len_n; i++)
{
if (a_num[i] == inputnum)
{
a_freq[i] = a_freq[i] + 1;
break;
}
}
// add inputnum into the array if it hasn't already been seen
if (i == len_n)
{
a_num[i] = inputnum;
a_freq[i] = 1;
// Update len_n
len_n++;
}
// Check if we have already reached 1000
if (1000 == len_n)
{
printf("Reached 1000 entry read\n");
break;
}
// Next entry
inputnum = getint();
}
// print the number with the highest frequency
int max_freq = ar_max(a_freq);
for (j = 0; j < len_n; j++)
{
if (a_freq[j] == max_freq)
{
printf("%d\n", a_num[j]);
break;
}
}
}
注意:
1. #define MAX_SIZE 1000可以使用,因为在代码中重复使用硬编码值1000。当您使用新尺寸(例如1500)并且只需更改#define MAX_SIZE 1500时,这将有所帮助,其他代码保持不变。
2.可以修改ar_max()函数以给出max发生的数组索引,以避免main中的for循环找到数组索引。例如
int ar_max(int a[])
{
int index = 0;
int max_so_far = a[0];
for (int i = 1; i < 1000; i++) {
if (a[i] > max_so_far) {
max_so_far = a[i];
index = i;
}
}
return index;
}
在main()中:
printf("%d\n", a_num[ar_max(a_freq)]);