【问题标题】:Remove duplicate Maximum and Minimum from unsorted array从未排序的数组中删除重复的最大值和最小值
【发布时间】:2016-07-29 09:39:55
【问题描述】:

我目前有一些包含以下值的数组

var array = new[] { 4, 7, 9, 3, 8, 6, 4, 3, 3, 9};

我需要删除最小值和最大值的重复项,因此在这种情况下,最终产品将是

var array = new[] { 4, 7, 9, 3, 8, 6, 4};

【问题讨论】:

  • 你应该首先对你的数组进行排序
  • 如果他需要该数组,则不会以相同的顺序排列。
  • 如果 min 和 max 是相同的值,结果数组应该只是一个元素数组吗?或两个如果原件中有两个以上的元素?
  • @IssakMadden 你应该接受一个适合你需要的答案

标签: c# arrays duplicates


【解决方案1】:

----------已编辑-------------- ----

////Correct        
        Int32[] arr = { 4, 7, 9, 3, 8, 6, 4, 3, 3, 9 };
        List<Int32> newArr = new List<Int32>();
        Int32 max = arr.Max();
        Int32 min = arr.Min();
        Boolean removeMax = false;
        Boolean removeMin = false;

        foreach (var each in arr)
        {                
            if (each == min || each == max)
            {
                if (!removeMax || !removeMin)
                {
                    if (each == min)
                    {
                        newArr.Add(each);
                        removeMin = true;
                    }

                    if (each == max)
                    {
                        newArr.Add(each);
                        removeMax = true;
                    }                        
                }
            }
            else
            {
                newArr.Add(each);
            }               
        }
        var arrAfter = newArr.ToArray();           

【讨论】:

  • 只需要删除最大值和最小值。并非所有重复。
  • 有趣,继续尝试
  • 希望看到更好的解决方案,我知道这不是完美的解决方案
【解决方案2】:

这将只需要迭代array 两次。

 var max = int.MinValue;
 var min = int.MaxValue;
 var array = new [] { 4, 7, 9, 3, 8, 6, 4, 3, 3, 9 };
 // Get min and max values. With just one iteration.
 foreach (var element in array)
     {
     if (element < min)
         {
         min = element;
         }
     if (max < element)
         {
         max = element;
         }
     }

 var minCount = 0;
 var maxCount = 0;
 var list = array.ToList ();
 // Search for duplicates with second iteration.
 for (int i = 0; i < list.Count; ++i)
     {
     if (list[i] == min)
         {
         if (minCount++ != 0)
             {
             list.RemoveAt (i--);
             }
         continue;
         }
     if (list[i] == max)
         {
         if (maxCount++ != 0)
             {
             list.RemoveAt (i--);
             }
         }
     }
 array = list.ToArray ();

【讨论】:

    【解决方案3】:

    如果性能不是问题那么这样的事情会起作用

    var min = arr.Min();
    var max = arr.Max();
    
    bool foundMin = false, foundMax = false;
    var result = arr
                   .Where(a=>!((a==min && foundMin) || (a==max &&foundMax)))
                   .Select(a=>{ 
                        if(a==min) 
                        {
                           foundMin = true;
                        }
                        else if(a==max) 
                        {
                          foundMax = true;
                        }
    
                        return a;
                }).ToArray();
    

    我想不出用少于两次的方法来做到这一点,所以我能看到的唯一改进是创建一个循环来同时找到最小值和最大值

    int min,max;
    for(int i=0;i<arr.length;i++)
    {
        if(i==0) min = max = arr[i];
        else if(arr[i]<min) 
        {
            min = arr[i];
        } 
        else if (arr[i]>max)
        {
            max = arr[i];
        }
    }
    

    但如果您不关心性能,只需使用内置的 linq 方法,因为它的代码较少,但前提是性能不是问题

    作为常规循环

    //assuming calculated min & max with loop or .Min & .Max linq extensions
    var newLs = new List<int>();
    int[] result;
    bool foundMin = false, foundMax = false;
    foreach(var val in arr)
    {
        if(val == min)
        {
            if(foundMin) continue;
            foundMin = true;
        }
        if(val == max)
        {
           if(foundMax) continue;
           foundMax = true;
        }
    
        newLs.Add(val);
    }
    
    result = newLs.ToArray();
    

    【讨论】:

      【解决方案4】:
          var ar = new[] { 4, 7, 9, 3, 8, 6, 4, 3, 3, 9 };
          var max = ar.Max();
          var min = ar.Min();
          var bmin = 0;
          var bmax = 0;
          var res = ar.Where(i => (i > min || 0 == bmin++) && (i < max || 0 == bmax++));
      

      【讨论】:

      • 在我的电脑上工作.. 似乎 dontnetfildle 不做后增量权利
      • +1 在遍历 foreach 循环时似乎工作正常,请参阅:dotnetfiddle.net/DfbjH3,酷使用 bool eval 短路
      • Marco Bong,根据 C# 规则,++ 在 == 之后工作,|| 的右侧如果左侧为真,则不评估。所以 bmin 只有在满足最小值后才会增加,并且第一个 min 被视为那时 bmin 仍然是 0。与 bmax 相同。
      • 谢谢,只是无法想象它在 Where(i=>) 子句中的实际工作方式,也许有一天我会在遇到类似问题时明白。 :)
      猜你喜欢
      • 2022-10-23
      • 1970-01-01
      • 1970-01-01
      • 2016-07-13
      • 1970-01-01
      • 1970-01-01
      • 2020-03-10
      • 2018-10-02
      • 2017-08-01
      相关资源
      最近更新 更多