1

What is the best algorithm to take array like below:

A {0,1,2,3}

I expected to order it like array below:

B {3,1,0,2}

Any ideas?

4

7 回答 7

6

So if you have two arrays and they hold the same data just in different order then just do this:

A = B

I suspect that is not your situation so I think we need more info.

于 2008-09-04T17:40:25.380 回答
3

您需要做的是确定 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;
}

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

于 2008-09-04T17:47:40.557 回答
2

这是我的比较器实现(使用 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
}
于 2010-11-24T17:16:53.003 回答
1

In the example you gave (an array of numbers), there would be no point in re-ordering A, since you could just use B.

So, presumably these are arrays of objects which you want ordered by one of their properties.

Then, you will need a way to look up items in A based on the property in question (like a hashtable). Then you can iterate B (which is in the desired sequence), and operate on the corresponding element in A.

于 2008-09-04T17:42:36.793 回答
1

Both array's contain the same values (or nearly so) but I need to force them to be in the same order. For example, in array A the value "3045" is in index position 4 and in array B it is in index position 1. I want to reorder B so that the index positions of like values are the same as A.

于 2008-09-04T17:42:48.900 回答
1

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

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
于 2008-09-04T17:47:11.667 回答
1

是否可以使用字典解决问题,以便元素具有根本不基于排序顺序的关系?

于 2009-03-23T16:28:55.893 回答