我正在做一个小实验来增加我的知识,我已经达到了一个我认为我可以真正优化它的部分,但我不太确定如何做到这一点。
我有很多数字。 (为简单起见,假设每个数组都有4个数字:1,2,3和4)
目标是按升序排列所有数字(即 1-2-3-4),但数字都在不同的数组中加扰。
较大的数字会增加较高的重量。
我需要按照它们的接近程度对所有这些数组进行排序 目标。
一些示例案例:
3-4-2-1 is better than 4-3-2-1
2-3-4-1 is better than 1-4-3-2 (even though two numbers match (1 and 3).
the biggest number is closer to its spot.)
因此,大数字总是优先于较小的数字。这是我的尝试:
var tmp = from m in moves
let mx = m.Max()
let ranking = m.IndexOf(s => s == mx)
orderby ranking descending
select m;
return tmp.ToArray();
上面例子中的P.SindexOf是我写的一个扩展,用于获取数组和表达式,并返回满足表达式的元素的索引。这是必要的,因为情况确实有点复杂,我用我的例子简化它。
我在这里尝试的问题是,它只会按最大数字排序,而忘记所有其他数字。它应该首先按最大数量排名,然后按第二大排名,然后排在第三位。
此外,由于它会一遍又一遍地执行此操作几分钟,因此它应该尽可能高效。
答案 0 :(得分:1)
您可以实施冒泡排序,并计算您必须移动数据的次数。在远离排序理想的阵列上,数据移动的数量会很大。
int GetUnorderedness<T>(T[] data) where T : IComparable<T>
{
data = (T[])data.Clone(); // don't modify the input data,
// we weren't asked to actually sort.
int swapCount = 0;
bool isSorted;
do
{
isSorted = true;
for(int i = 1; i < data.Length; i++)
{
if(data[i-1].CompareTo(data[i]) > 0)
{
T temp = data[i];
data[i] = data[i-1];
data[i-1] = temp;
swapCount++;
isSorted = false;
}
}
} while(!isSorted);
}
从您的示例数据中,这将得到与您指定的略有不同的结果。
一些示例案例:
3-4-2-1优于4-3-2-1
2-3-4-1优于1-4-3-2
3-4-2-1
将进行5次互换排序,4-3-2-1
将需要6次,因此有效。
2-3-4-1
将占用3,1-4-3-2
也将占用3,因此这与您的预期结果不符。
此算法不会将最大数字视为最重要的数字,这似乎是您想要的;所有数字都得到平等对待。根据您的描述,您认为2-1-3-4
比1-2-4-3
更好,因为第一个数字在适当的位置包含最大和第二大数字。这个算法会认为这两个相等,因为每个只需要1个交换来对数组进行排序。
该算法的优势在于它不仅仅是一个比较算法,每个输入都有一个离散输出,所以你只需要为每个输入数组运行一次算法。
答案 1 :(得分:0)
我希望这会有所帮助
var i = 0;
var temp = (from m in moves select m).ToArray();
do
{
temp = (from m in temp
orderby m[i] descending
select m).ToArray();
}
while (++i < moves[0].Length);