我有一段时间难过这个.我想获取一个列表并订购列表,以便最大价格的产品最终位于列表中间.而且我也想做相反的事情,即确保价格最高的项目最终在列表的外边界上.
想象一下像这样的数据结构.. 1,2,3,4,5,6,7,8,9,10
在第一个场景中,我需要回到1,3,5,7,9,10,8,6,4,2在第二个场景中,我需要回到10,8,6,4,2,1,3 ,5,7,9
该列表可能有超过250个项目,数字将不会均匀分布,并且它们不会是连续的,我想尽量减少复制.数字将包含在Product对象中,而不是简单的原始整数.
是否有一个我没有看到的简单解决方案?
有什么想法吗.
所以对于那些想知道我在做什么的人,我根据计算出的字体大小来订购商品.这是我去的代码......
实施......
private void Reorder()
{
var tempList = new LinkedList<DisplayTag>();
bool even = true;
foreach (var tag in this) {
if (even)
tempList.AddLast(tag);
else
tempList.AddFirst(tag);
even = !even;
}
this.Clear();
this.AddRange(tempList);
}
Run Code Online (Sandbox Code Playgroud)
考试...
[TestCase(DisplayTagOrder.SmallestToLargest, Result=new[]{10,14,18,22,26,30})]
[TestCase(DisplayTagOrder.LargestToSmallest, Result=new[]{30,26,22,18,14,10})]
[TestCase(DisplayTagOrder.LargestInTheMiddle, Result = new[] { 10, 18, 26, 30, 22, 14 })]
[TestCase(DisplayTagOrder.LargestOnTheEnds, Result = new[] { 30, 22, 14, 10, 18, 26 })]
public int[] CalculateFontSize_Orders_Tags_Appropriately(DisplayTagOrder sortOrder)
{
list.CloudOrder = sortOrder;
list.CalculateFontSize();
var result = (from displayTag in list select displayTag.FontSize).ToArray();
return result;
}
Run Code Online (Sandbox Code Playgroud)
用法......
public void CalculateFontSize()
{
GetMaximumRange();
GetMinimunRange();
CalculateDelta();
this.ForEach((displayTag) => CalculateFontSize(displayTag));
OrderByFontSize();
}
private void OrderByFontSize()
{
switch (CloudOrder) {
case DisplayTagOrder.SmallestToLargest:
this.Sort((arg1, arg2) => arg1.FontSize.CompareTo(arg2.FontSize));
break;
case DisplayTagOrder.LargestToSmallest:
this.Sort(new LargestFirstComparer());
break;
case DisplayTagOrder.LargestInTheMiddle:
this.Sort(new LargestFirstComparer());
Reorder();
break;
case DisplayTagOrder.LargestOnTheEnds:
this.Sort();
Reorder();
break;
}
}
Run Code Online (Sandbox Code Playgroud)
适当的数据结构是LinkedList因为它允许您有效地添加到任何一端:
LinkedList<int> result = new LinkedList<int>();
int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Array.Sort(array);
bool odd = true;
foreach (var x in array)
{
if (odd)
result.AddLast(x);
else
result.AddFirst(x);
odd = !odd;
}
foreach (int item in result)
Console.Write("{0} ", item);
Run Code Online (Sandbox Code Playgroud)
没有额外的复制步骤,没有反向步骤,......每个节点只需要很小的开销用于存储.
(非常简单的代码,以满足所有条件.)
一个功能来统治它们!不使用中间存储集合(请参阅yield关键字).根据参数将大数字排序到中间或侧面.它是作为C#迭代器实现的
// Pass forward sorted array for large middle numbers,
// or reverse sorted array for large side numbers.
//
public static IEnumerable<long> CurveOrder(long[] nums) {
if (nums == null || nums.Length == 0)
yield break; // Nothing to do.
// Move forward every two.
for (int i = 0; i < nums.Length; i+=2)
yield return nums[i];
// Move backward every other two. Note: Length%2 makes sure we're on the correct offset.
for (int i = nums.Length-1 - nums.Length%2; i >= 0; i-=2)
yield return nums[i];
}
Run Code Online (Sandbox Code Playgroud)
例如,使用数组 long[] nums = { 1,2,3,4,5,6,7,8,9,10,11 };
从正向排序顺序开始,将高数字压入中间.
Array.Sort(nums); //forward sort
// Array argument will be: { 1,2,3,4,5,6,7,8,9,10,11 };
long[] arrLargeMiddle = CurveOrder(nums).ToArray();
Run Code Online (Sandbox Code Playgroud)
产量:1 3 5 7 9 11 10 8 6 4 2
或者,从反向排序顺序开始,将高数字推向两侧.
Array.Reverse(nums); //reverse sort
// Array argument will be: { 11,10,9,8,7,6,5,4,3,2,1 };
long[] arrLargeSides = CurveOrder(nums).ToArray();
Run Code Online (Sandbox Code Playgroud)
产生:11 9 7 5 3 1 2 4 6 8 10
重要的命名空间是:
using System;
using System.Collections.Generic;
using System.Linq;
Run Code Online (Sandbox Code Playgroud)
注意:迭代器会决定是否使用中间存储来决定调用者.调用者可能只是foreach在结果上发出循环.
(可选)更改静态方法标头以使用this修饰符 public static IEnumerable<long> CurveOrder(this long[] nums) { 并将其放在命名空间中的静态类中;
然后直接在任何long []数组实例上调用order方法,如下所示:
Array.Reverse(nums); //reverse sort
// Array argument will be: { 11,10,9,8,7,6,5,4,3,2,1 };
long[] arrLargeSides = nums.CurveOrder().ToArray();
Run Code Online (Sandbox Code Playgroud)
只是一些(不需要的)语法糖来混合一些东西以获得乐趣.这可以应用于采用数组参数的问题的任何答案.