【问题标题】:Order an Array like another Array in C#像 C# 中的另一个数组一样订购一个数组
【发布时间】:2010-09-07 20:09:45
【问题描述】:

以下数组的最佳算法是什么:

A {0,1,2,3}

我希望像下面的数组一样订购它:

B {3,1,0,2}

有什么想法吗?

【问题讨论】:

  • 你能说A中的所有元素是否都会存在于B中吗?我认为如果某些元素不在 A 中也没关系。相反的可能性会产生类似未定义的结果 - 尽管你可以让它们落到最后。

标签: c# arrays


【解决方案1】:

因此,如果您有两个数组并且它们以不同的顺序保存相同的数据,那么只需执行以下操作:

A = B

我怀疑这不是你的情况,所以我认为我们需要更多信息。

【讨论】:

    【解决方案2】:

    您需要做的是确定 B 的排序,然后将该排序应用于 A。实现此目的的一种方法是撤消 B 的排序并跟踪沿途发生的情况。然后你可以对A做相反的事情。

    这里有一些粗略的 C#(抱歉,我还没有实际运行过)...

    复制B:

    List<int> B2 = new List<int>(B);
    

    现在使用记录交换的排序函数对其进行排序:

    List<KeyValuePair<int,int>> swaps = new List<KeyValuePair<int,int>>();
    B2.Sort( delegate( int x, int y ) {
       if( x<y ) return -1;
       if( x==y ) return 0;
       // x and y must be transposed, so assume they will be:
       swaps.Add( new KeyValuePair<int,int>(x,y) );
       return 1;
    });
    

    现在以相反的顺序将交换应用到 A:

    swaps.Reverse();
    foreach( KeyValuePair<int,int> x in swaps )
    {
       int t = A[x.key];
       A[x.key] = A[x.value];
       A[x.value] = t;
    }
    

    根据内置排序算法的工作方式,您可能需要自己滚动。像合并排序这样的非破坏性的东西应该会给你正确的结果。

    【讨论】:

    • 我喜欢这个。这是一个位置分析。不过,在资源方面可能很昂贵(mem 和 proc)。
    【解决方案3】:

    这是我的比较器实现(使用 LINQ,但可以轻松适应较旧的 .net 版本)。您可以将它用于任何排序算法,例如 Array.Sort、Enumerable.OrderBy、List.Sort 等。

    var data = new[] { 1, 2, 3, 4, 5 };
    var customOrder = new[] { 2, 1 };
    Array.Sort(data, new CustomOrderComparer<int>(customOrder));
    foreach (var v in data)
        Console.Write("{0},", v);
    

    结果是2,1,3,4,5, - customOrder 中未列出的任何项目都放在给定类型的默认值的末尾(除非给出后备比较器)

    public class CustomOrderComparer<TValue> : IComparer<TValue>
    {
        private readonly IComparer<TValue> _fallbackComparer;
        private const int UseDictionaryWhenBigger = 64; // todo - adjust
    
        private readonly IList<TValue> _customOrder;
        private readonly Dictionary<TValue, uint> _customOrderDict;
    
        public CustomOrderComparer(IList<TValue> customOrder, IComparer<TValue> fallbackComparer = null)
        {
            if (customOrder == null) throw new ArgumentNullException("customOrder");
    
            _fallbackComparer = fallbackComparer ?? Comparer<TValue>.Default;
    
            if (UseDictionaryWhenBigger < customOrder.Count)
            {
                _customOrderDict = new Dictionary<TValue, uint>(customOrder.Count);
                for (int i = 0; i < customOrder.Count; i++)
                    _customOrderDict.Add(customOrder[i], (uint) i);
            }
            else
                _customOrder = customOrder;
        }
    
        #region IComparer<TValue> Members
    
        public int Compare(TValue x, TValue y)
        {
            uint indX, indY;
            if (_customOrderDict != null)
            {
                if (!_customOrderDict.TryGetValue(x, out indX)) indX = uint.MaxValue;
                if (!_customOrderDict.TryGetValue(y, out indY)) indY = uint.MaxValue;
            }
            else
            {
                // (uint)-1 == uint.MaxValue
                indX = (uint) _customOrder.IndexOf(x);
                indY = (uint) _customOrder.IndexOf(y);
            }
    
            if (indX == uint.MaxValue && indY == uint.MaxValue)
                return _fallbackComparer.Compare(x, y);
    
            return indX.CompareTo(indY);
        }
    
        #endregion
    }
    

    【讨论】:

    • Upboat 用于 (uint) IndexOf() 比较。
    【解决方案4】:

    在您给出的示例(数字数组)中,重新排序 A 没有意义,因为您可以只使用 B。

    因此,大概这些是您希望按其属性之一排序的对象数组。

    然后,您将需要一种方法来根据相关属性(如哈希表)在 A 中查找项目。然后就可以迭代B(按照想要的顺序),对A中对应的元素进行操作。

    【讨论】:

      【解决方案5】:

      两个数组包含相同的值(或几乎相同),但我需要强制它们以相同的顺序排列。例如,在数组 A 中,值“3045”位于索引位置 4,而在数组 B 中,它位于索引位置 1。我想对 B 重新排序,以便类似值的索引位置与 A 相同。

      【讨论】:

      • 请不要用答案来澄清您的问题,请编辑您的原始问题以包含其他信息。因为答案是按投票排序的,这意味着您的说明将始终位于底部。这也意味着你在澄清你的答案方面获得了声誉,这并不好。
      【解决方案6】:

      如果它们几乎相同,那么这里有一些伪代码:

      Make an ArrayList
      Copy the contents of the smaller array to the arraylist
      for each item I in the larger array
          FInd I in the ArrayList
          Append I to a new array
          Remove I from the arraylist
      

      【讨论】:

        【解决方案7】:

        是否可以使用字典解决问题,使元素之间的关系完全不取决于排序顺序?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-30
          • 2014-05-07
          • 1970-01-01
          • 2020-11-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多