【问题标题】:3 Highest Numbers in an array without sorting, Where am I missing the logic? [closed]3 没有排序的数组中的最高数字,我在哪里错过了逻辑? [关闭]
【发布时间】:2015-09-28 05:06:37
【问题描述】:

此程序用于在数组中查找 3 个最高的数字。

当我运行代码时,我得到了第一高和第二高。第二高的是第三个数字重复

我在逻辑中遗漏了什么?

#include<stdio.h>
#include<conio.h>

int main()
{
   int i,k,n,m[20],h[3];
   printf("\n enter the total number of students");
   scanf("%d",&n);
   for(i=0;i<n;i++)
   {
      printf("enter the marks scored by student %d",i+1);
      scanf("%d",&m[i]);
   }//end for loop
   k=0;
   h[k]=m[0];
   for(i=0;i<n;i++)
   {
      if(m[i]>h[k])
      {
         h[k]=m[i];
      }
   }//end for loop
   do
   {
      //Probably messed my code here
      k++;
      h[k]=m[0];
      for(i=0;i<n;i++)
      {
         if(m[i]>=h[k-1])
         {
            if(m[i]>h[k])
            {
               h[k]=m[i];
            }//end if
            break;
         }//end if
      }//end for loop
   }//end do loop
   while(k<3);
   printf("the first 3 highest marks are:\n");
   for(i=0;i<k;i++)
      printf("%d:%d\n",i+1,h[i]);
   getch();
}//end of main

【问题讨论】:

  • 有两种方法可以解决这样的问题: 1) 在调试器中运行您的代码,一次单步执行一行,观察变量值,直到您发现它在哪里没有做您想做的事情想; 2) 在代码中的关键点插入输出语句 (printf) 以查看发生了什么。 SO 的工作方式不是:“这是我的代码,请为我调试”。你调试它,然后在解释你做了什么之后问你是否仍然不明白。
  • 是您想要的前 3 个数字还是可以更多(将来)?
  • 列表总是唯一数字的集合吗?
  • 额外问题:为什么 m[] 的一个成员在 do-while 循环的最后一步发生了变化?

标签: c arrays sorting highest


【解决方案1】:

我不知道,如果可以以更简单的方式完成,那么您编写这么多行代码的目的是什么。 这是在一次迭代中找到前 3 个数字的另一种方法; 希望您会喜欢它,它可能会在将来对您有所帮助。

来源:

#include<stdio.h>
#include<limits.h>
int main()
{
    int a[10] = {5,4,3,6,7,8,9,10,1,2};
    int h1 = INT_MIN; //TOP 1st
    int h2 = INT_MIN; //TOP 2nd
    int h3 = INT_MIN; //TOP 3rd
    for(int i=0;i<10;i++)
    {
        if(a[i] > h1)
        {
            h3 = h2; h2 = h1; h1 = a[i];
        }
        else if (a[i] > h2)
        {
            h3 = h2; h2 = a[i];
        }
        else if  (a[i] > h3)
        {
            h3 = a[i];
        }
    }
    printf("TOP 1st is<%d>\n",h1);
    printf("TOP 2nd is<%d>\n",h2);
    printf("TOP 3rd is<%d>\n",h3);
    return 0;
}

输出:

./a.out 
TOP 1st is<10>
TOP 2nd is<9>
TOP 3rd is<8>

【讨论】:

  • int a[10] = {5,4,3,9,6,8,2,7,1};
  • @NitinTripathi,这不是问题所在。问题是如果最大的数字出现在第二和第三大数字之前,您的逻辑就不起作用。
  • 你做一个小改动让它工作。
  • int a[10] = {10,4,3,6,7,8,9,5,1,2};
  • @user3386109,感谢您指出问题,使用limits.c 中定义的INT_MIN 更正初始化。希望它现在可以工作。再次感谢。
【解决方案2】:

我看到以下问题:

  1. 线

    h[k]=m[0];
    

    如果m[0] 是最大或第二大的值会导致问题。将其更改为:

    h[k]=INT_MIN;
    
  2. 线

     if(m[i]>=h[k-1])
    

    似乎错了。那应该是

     if(m[i] < h[k-1])
    
  3. 线

        break;
    

    是错误的来源。如果第二个和第三个最大值接近列表的末尾,它将无法正确检测它们。

这是带有这些修复的 do/while 块。

do
{
   k++;
   h[k]=INT_MIN;
   for(i=0;i<n;i++)
   {
      if(m[i] < h[k-1])
      {
         if(m[i]>h[k])
         {
            h[k]=m[i];
         }//end if
      }//end if
   }//end for loop
}//end do loop

这似乎对我有用。

【讨论】:

    【解决方案3】:

    你的问题之一是生产线

    if(m[i]>=h[k-1])
    

    这个条件将在你的 do...while 循环的每次迭代中被满足一次(假设最高标记只出现一次),并且只有当最高数字不是第一个时才会执行下一行.

    这不是代码的唯一问题。 Nitin Tripathi 的 cmets 提到,在很多情况下这段代码都不能正常工作。

    我建议您使用前三个标记加载 h 数组。然后,使用冒泡排序算法对其进行排序,使 h[0] 最高,h[2] 最低。然后迭代标记的剩余值。对于每个值,如果它高于 h[2],则用它替换 h[2],并使用相同的冒泡排序算法对 h 数组进行重新排序。你可以用谷歌搜索并找到很多例子。

    注释您的代码也可能对您有很大帮助。

    【讨论】:

      【解决方案4】:

      您需要对 h 数组进行排序,以下代码工作正常

      #include<stdio.h>
      #include<conio.h>
      
      void main()
      {
         int i,a,j,k,n,m[20],h[3];
         int high, temp;
         printf("\n enter the total number of students");
         scanf("%d",&n);
         for(i=0;i<n;i++)
         {
            printf("enter the marks scored by student %d",i+1);
            scanf("%d",&m[i]);
         }//end for loop
      
         k=0;
         h[k]=m[0];
      
         for(i = 1; i < n; i++)
         {
            if(m[i] > h[0])
            {
           h[k] = m[i];
           k++;
      
           // make sure h[0] have max value out of all 3
           for (a = 0; a < k; a++)
           {
              for (j = a + 1; j < k; j++)
              {
                  if (h[a] < h[j])
                  {
                      temp = h[j];
                      h[j] = h[a];
                      h[a] = temp;
                  }
              }
           }
            }
         }//end for loop
      
      
         for (i = 0; i < k; i++)
         {
          printf("\n %d", h[i]);
         }
      
         getch();
      }
      

      【讨论】:

        【解决方案5】:
        #include <algorithm>
        #include <cstddef>
        
        template<typename RanIt>
        void make_N_highest( std::size_t N, RanIt b, RanIt e )
        {
            std::make_heap(b,e);
            while(N--)
                std::pop_heap(b,e--);
        }
        

        这会将 N 个最高值放在序列的最后。
        这是 O( N * log(size) )

        【讨论】:

        猜你喜欢
        • 2016-02-22
        • 1970-01-01
        • 2014-12-28
        • 2019-12-13
        • 1970-01-01
        • 1970-01-01
        • 2022-01-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多