【问题标题】:I don't understand why my for loop gives an awkward output我不明白为什么我的 for 循环给出了一个尴尬的输出
【发布时间】:2020-04-07 10:53:57
【问题描述】:

不幸的是......我昨天问了这个关于另一个错误的问题,希望我不再有这些错误,但我仍然有这个尴尬的输出,比如某种取决于数组元素的数字,如 -4221565 或-4647963 等...直到现在我认为我的数组附加部分工作正常,我试过了。但我猜想条件中的 -1 有问题,但我不能说出它的名字。 For循环也是我想说的另一个地方。我从凌晨 3 点开始尝试解决这个问题,然后拖延,然后尝试...截止日期是 7.04.2020(今天)22.00,所以我开始发疯了。任何帮助将不胜感激。谢谢。所以这是个问题(输入不必是 15,最多可以是 15):

您必须将最多 15 种不同的货物从一个港口运送到另一个港口。运输这些货物的货船的承载能力为 50 吨。枚举负载,并提供有关每个负载重量的信息作为输入。

假设每件货物的重量小于等于50吨且大于0。

您将在一行中从输入中读取每个负载的重量。您的输入将以 -1 结尾。您将打印必要的旅行次数。

示例输入:

50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 -1

输出:15

输入: 20 25 25 36 37 25 20 10 50 9 16 45 32 10 25 -1

输出: 11

输入: 14 16 50 10 10 19 45 40 32 24 25 47 10 12 25 -1

输出: 9

输入: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 -1

输出: 3

这是我的代码:

#include <stdio.h>
int main()
{   int w,i,sum,index;
    int list[15];
    w = 1;
    index = 0;
    do
    {   scanf("%d",&w);
        list[index] = w;
        index++;
    }while(w != -1);
    sum = 0;
    for(i = 0;i < 15;i++)
    {
        sum +=list[i];
    }
        sum = sum / 50;
        printf("%d",sum);
    return 0;

}

【问题讨论】:

  • 您的循环将 -1 存储在 15 元素数组的不存在的第 16 个元素中,这样做会调用 未定义的行为。将你的循环改为一个while循环,特别是while (index &lt; 15 &amp;&amp; scan("%d", &amp;w) == 1 &amp;&amp; w != -1) { list[index++] = w; }
  • 将 do-while 更改为 while(1) { scanf("%d", &amp;w); if(w==-1) break; list[index] = w; index++}
  • 在循环遍历和求和值时输入的整数少于 15 个的情况下,您仍在对数组中未设置为值的值求和。您正在对未定义的值求和,这就是您得到奇怪负数的原因之一。你应该只在求和循环中循环比索引少一。
  • 而且,相关的,你不需要一个数组,你可以很容易地将sum += w; 放入循环中,而不是存储在一个数组中,碰到一个计数器并将其用作你的稍后的元素计数(无论如何你似乎都没有使用它,这本身就是一个缺陷)。
  • 任务也没有很好的制定。它并没有说你可以按照你想要的任何顺序选择它们,但它也没有禁止它。如果允许以任意顺序选择它们,则第二种情况可能有 7 次行程。

标签: c arrays for-loop logic knapsack-problem


【解决方案1】:

在您的代码中,您传递的数组边界 -1 将是数组的第 16 个元素,这是错误的。你至少需要int list[16];。

但是您的解决方案是错误的,您正在根据给定的输入和输出判断负载将它们放置在货船上。例如,如果一艘船上有 30 个和 10 个,您不能将 20 个负载分成两个 10 个负载,以便在船上放置最多 50 吨的负载。

你需要的是:

  1. 考虑一艘载有0 ton 的船

  2. 当负载总和小于或等于50时添加负载

  3. 如果添加新负载后,当前船舶的总和高于50 counter_ship++,然后将该负载添加到新负载中。

int main(void) {
    int w;
    int sum = 0;
    int ship_counter = 0;
    scanf("%d", &w);

    while (w != -1) {
        if (sum + w > 50)
        {
            ship_counter++;
            sum = 0;
        }
        sum += w; 
        scanf("%d", &w);
    }
    if (sum != 50)
        ship_counter++;
    printf("%d", ship_counter);

    return 0;
}  

【讨论】:

  • 非常感谢,这样理解起来更加简单明了,多亏了你,我才能提交我的代码。我将继续尝试使用 do-while 循环、数组、for 循环来解决它……我猜所有可能的方法。睡一觉之后。
  • @IDK 随意,无需感谢,但如果这有帮助,请接受答案。
  • “你可以把一个 20 的负载分成两个 10 的负载” 你是说不能吗?你说得对,但我想那是一个错字。
【解决方案2】:

您需要对数组进行排序。然后,您需要检查阈值金额。如果超过了,则添加一个容器。

#include <stdio.h>
void swap(int* xp, int* yp) 
{ 
    int temp = *xp; 
    *xp = *yp; 
    *yp = temp; 
} 

// Function to perform Selection Sort 
void selectionSort(int arr[], int n) 
{ 
    int i, j, min_idx; 

    // One by one move boundary of unsorted subarray 
    for (i = 0; i < n - 2; i++) { 

        // Find the minimum element in unsorted array 
        min_idx = i; 
        for (j = i + 1; j < n-1; j++) 
            if (arr[j] < arr[min_idx]) 
                min_idx = j; 

        // Swap the found minimum element 
        // with the first element 
        swap(&arr[min_idx], &arr[i]); 
    } 
} 

int main()
{   int w,i,sum,index;
    int list[15];
    w = 1;
    index = 0;
    do
    {   scanf("%d",&w);
        list[index] = w;
        index++;
    }while(w != -1);

    selectionSort(list,index);

    for (int i = 0; i < index; i++) 
        printf("%d ", list[i]); 
    printf("\n"); 

    int ans=0;
    int threshold=0;
    for(int i=0; i<index; ++i){
        if(threshold + list[i]<=50){
            threshold+=list[i];
        }
        else {
            threshold = list[i];
            ++ans;
        }
    }
    ans++;
    printf("%d", ans);
    return 0;

}

【讨论】:

  • 不需要排序
  • 出于逻辑目的需要。
  • 我是语言新手,所以我需要进行一些研究才能理解这一点。我会慢慢来的。非常感谢您的帮助。
【解决方案3】:

将 do-while 循环改为这样的 while:

while(w != -1 && index < 15)
{   scanf("%d",&w);
    list[index] = w;
    index++;
}

这样可以避免写入超出数组的边界。

那么,for循环的条件可以是:

for(i = 0;i &lt; index; i++)

(index的值来自上一个循环,只到最后插入的下一项)。 所以你是在总结实际有输入的项目,而不是整个数组。

正如其他人评论的那样,您当然可以不使用数组。

希望有帮助

【讨论】:

  • 感谢您的时间和精力,它澄清了一些事情。
【解决方案4】:

你的代码有几个问题,我感觉不太好去改进其中仍然存在逻辑问题的地方,所以我做了一些我通常不会做的事情(因为显然你似乎对此感到非常紧张,而且你处于快点)并为您提供我自己的任务版本:

#include <stdio.h>

#define MAX_LOADS 15
#define MAX_CAP 50

int main()
{
    int w[MAX_LOADS+1];
    int trips = 0;
    int i = 0;
    int sum = 0;
    int max = 0;
    int loads = 0;
    int rest = 0;

    printf("Enter the Weights of the Loads:\n");    

    while(i < (MAX_LOADS + 1))
    {
        scanf(" %d",&w[i]);
        printf(" ");
        if(w[i] == -1)
        {
            break;
        }
        sum = sum + w[i];

        loads++;
        i++;
    }

    printf("\n");

    printf("%d Loads have a weight of %d tons.\n", loads, sum);

    if(sum <= MAX_CAP)
    {
         printf("The amount of needed trips are: 1");
    }
    else
    {
         for(int i = 0; i < loads; i++)
         {
             if(w[i] == MAX_CAP)
             {
                 w[i] = 0;
                 trips++;
                 continue; 
             }
             else if(w[i] < MAX_CAP && w[i] > 0)
             {
                 rest = MAX_CAP - w[i];
                 w[i] = 0;

                 for(int j = 0; j < loads; j++)
                 {
                     if(i == j)
                     continue;

                     if(w[j] == rest)
                     {
                        w[j] = 0;
                        break;
                     }
                     else if(w[j] < rest && w[j] > 0)
                     {
                        rest = rest - w[j];
                        w[j] = 0;
                     } 

                     if(rest == 0)
                     {
                        break;
                     }
                 } 

                 trips++;
             }
         }

         printf("The amount of needed trips are: %d", trips);
    }

    return 0;    
}

输出/执行1:

Enter the Weights of the Loads:    
10 20 40 -1                    

3 Loads have a weight of 70 tons.
The amount of needed trips are: 2

输出/执行 2:

Enter the Weights of the Loads:          
50 50 50 50 50 -1   

5 Loads have a weight of 250 tons.              
The amount of needed trips are: 5

输出/执行 3:

Enter the Weights of the Loads:  
10 10 10 10 10 -1   

5 Loads have a weight of 50 tons.                               
The amount of needed trips are: 1 

【讨论】:

  • 我可以给你一个提示:OP的测试用例2
  • @ArdentCoder 所以现在我已经更正了。你怎么看?
  • 逻辑又出问题了。还有很多夸张的代码。
  • 仅供您有限的输入。例如,当输入为20 40 40 -1 时,看看您的输出会发生什么。它将给出2,因为100 = 50 * 2。但是您认为这些货物可以分两批运输吗?
  • @ArdentCoder 不,它打算这样做,是的,这就是我的想法:“运输这些货物的货船的承载能力是 50 吨. ... 假设每件货物的重量小于等于 50 吨且大于 0。” - 也就是说,这些货物可以分 2 批运输。
【解决方案5】:
#include <stdio.h>
#define MAX_SIZE 15
int main()
{  
    /* Let's define variables here. */
    int i=0,j=0 ;
    int input;
    int weights[MAX_SIZE];
    int  numberOfTrips = 0;
    int sum = 0;

  /* Inputs is taken  here from usre, Max = 15 */
    printf("Input:\n");
    scanf("%d",&input);
    while(input != -1){
        if (i< MAX_SIZE){
            if (input <= 50 &&  input>= 0){
                weights[i] = input;
                i = i  +1;

            } else printf("Wrong Input! \nPlease Enter value between 0 and 50\n");
        }

        else printf("You reach MAX_SIZE, please Enter -1 to see the Output");


        scanf("%d",&input);

    }

    printf("\n");
   /* We are going  will count the number of trips necessary*/
    if(input == -1){
        if (weights[0] != 0){
             /* Let's test the first value*/
          numberOfTrips = numberOfTrips +1;
        }
        sum= weights[0];
        for (j = 1; j<i; ++j){
          sum = sum +weights[j];

          if (sum>50){
            numberOfTrips = numberOfTrips +1;
            sum = weights[j];
          }
        }

    }
 /*Finally, let's print the output here.*/
    printf("Output:\n");
    printf("%d",numberOfTrips);

    return 0;
}

【讨论】:

    猜你喜欢
    • 2016-01-12
    • 2021-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-08
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    相关资源
    最近更新 更多