C# 根据其值对3个列表进行排序
我有3个列表,包含任意数量的双倍。现在我想将这些列表相互比较并排序。所有列表的长度都相同 排序的关系是: 比较每个元素。元素越多的列表,其顺序越高。我为两个列表编写了一个实现:C# 根据其值对3个列表进行排序,c#,.net,algorithm,C#,.net,Algorithm,我有3个列表,包含任意数量的双倍。现在我想将这些列表相互比较并排序。所有列表的长度都相同 排序的关系是: 比较每个元素。元素越多的列表,其顺序越高。我为两个列表编写了一个实现: public static bool isGreater(List<double> first, List<double> second) { int firstCounter = 0; int secondCounter = 0;
public static bool isGreater(List<double> first, List<double> second)
{
int firstCounter = 0;
int secondCounter = 0;
for (int i = 0; i < first.Count; i++)
{
if (first.ElementAt(i) > second.ElementAt(i))
{
firstCounter++;
}
else if (first.ElementAt(i) < second.ElementAt(i))
{
secondCounter++;
}
}
if (firstCounter > secondCounter)
{
return true;
}
else
{
return false;
}
}
publicstaticbool更大(先列表,后列表)
{
int firstCounter=0;
int secondCounter=0;
for(int i=0;i第二个元素(i))
{
firstCounter++;
}
else if(第一个元素(i)<第二个元素(i))
{
secondCounter++;
}
}
如果(第一计数器>第二计数器)
{
返回true;
}
其他的
{
返回false;
}
}
但是,如何将此代码改编为3个列表,甚至n个列表?列表的多样性是一种幻觉-只有一个列表,但每个项目都有一个属性来标识它来自哪个列表 合并列表,排序,然后拆分回其原始列表。需要执行的操作排序()根据您的排序定义创建列表集合。您应该能够使用标准排序,并为其提供自定义排序功能 算法类似于:
这个算法应该给出最大值O(mn lgN)(N列出每个大小M)。我知道有一种更快的(对数因子)随机算法可以找到最大值。你可以阅读。除非要处理大量列表,否则我不建议实现此算法。首先,使用已排序的集合不是更容易吗 你可以用它来做
关于如何将其应用于n-列表的问题,请使用递归,只需使用集合并跟踪最后的结果。这将允许您比较第一个和第三个列表,例如,如果递归函数的第一次迭代的结果返回第一个列表。使用数组为每个列表保留计数器 如果你有n个列表。你的阵列是计数器
void SortLists(List<List<double>> lists)
{
int[] counter = new int[lists.Count];
for (int i = 0; i < lists[0].Count; i++)
{
double MaxValue = double.MinValue;
int winningList = 0;
for (int j = 0; j < lists.Count; j++)
{
if(lists[j].ElementAt(i) > MaxValue )
{
MaxValue = lists[j].ElementAt(i);
winningList = j;
}
}
counter[winningList]++;
}
// sort the counter array, in effect your lists are sorted.
}
void排序列表(列表)
{
int[]计数器=新的int[lists.Count];
对于(int i=0;i<列表[0]。计数;i++)
{
double MaxValue=double.MinValue;
int winningList=0;
对于(int j=0;jMaxValue)
{
MaxValue=列表[j].ElementAt(i);
winningList=j;
}
}
计数器[赢取列表]+;
}
//对计数器数组进行排序,实际上列表已排序。
}
var list11=新列表{1,2,3};
var list22=新列表{4,5,3};
var list33=新列表{4,1,0};
int a计数器=0,b计数器=0,c计数器;
list11.Select((o,i)=>new{a=list11[i],b=list22[i]})
.Aggregate(0,(初始,项)=>项a>项b
?计数器++
:item.a==item.b
?B计数器
:b计数器++);
如果(A计数器>B计数器)
{
//对列表11和列表33执行相同的操作
}
其他的
{
//对列表22和列表33执行相同的操作
}
您可以对其进行重构,为两个列表编写一个函数,并为您想要的每一对调用该函数。
我对您的方法做了一些修改,并添加了另一个:
private static List<double> GetGreater(List<double> first, List<double> second)
{
int firstCounter = 0;
int secondCounter = 0;
for (int i = 0; i < first.Count; i++)
{
if (first.ElementAt(i) > second.ElementAt(i))
{
firstCounter++;
}
else if (first.ElementAt(i) < second.ElementAt(i))
{
secondCounter++;
}
}
// return the greater list instead of bool
return (firstCounter > secondCounter ? first : second);
}
public static List<double> Greater(params List<double>[] p)
{
// assumes the first list is the greater, then check the others
// this method assumes you will always pass at least 2 lists
List<double> greater = p[0];
for (var i = 1; i < p.Length; ++i)
{
greater = GetGreater(greater, p[i]);
}
return greater;
}
static void Main(string[] args)
{
// lists used for this test
var l1 = new List<double>() { 1, 222, 3 };
var l2 = new List<double>() { 1, 2, 4 };
var l3 = new List<double>() { 11, 222, 333 };
var l4 = Greater(l1, l2, l3); // l3
}
private static List GetGreater(列表第一,列表第二)
{
int firstCounter=0;
int secondCounter=0;
for(int i=0;i第二个元素(i))
{
firstCounter++;
}
else if(第一个元素(i)<第二个元素(i))
{
secondCounter++;
}
}
//返回更大的列表,而不是bool
返回(第一计数器>第二计数器?第一:第二);
}
公共静态列表更大(参数列表[]p)
{
//假设第一个列表较大,然后检查其他列表
//此方法假定您将始终传递至少2个列表
列表大于=p[0];
对于(变量i=1;i
我觉得您有一个“外部”列表,其中包含“内部”列表,您希望对“外部”列表进行排序。你可以这样做:
// Set up some input data
var outerList = new List<List<double>>();
outerList.Add(new List<double> { 2.0, 3.0, 3.0 });
outerList.Add(new List<double> { 1.0, 2.0, 3.0 });
outerList.Add(new List<double> { 2.0, 2.0, 3.0 });
// Sort the outer list
outerList.Sort((first, second) => isGreater(first, second) ? 1 : -1);
只要每个列表中的元素数量相同且已知,我就举一个小例子:
const int listSize = 6;
List<int> one = new List<int> { 0, 1, 2, 3, 4, 5 };
List<int> two = new List<int> { 10, 1, 9, 2, 8, 3 };
List<int> three = new List<int> { 5, 5, 5, 5, 5, 5 };
Dictionary<List<int>, int> lists = new Dictionary<List<int>, int>()
{
{one, 0},
{two, 0},
{three, 0}
};
for (int i = 0; i < listSize; i++)
{
var sortedAtIndex = lists.Keys.OrderByDescending(k => k[i]);
lists[sortedAtIndex.ElementAt(0)]++;
}
// And to show you that it works...
foreach (var element in lists.OrderByDescending(k => k.Value)
.Select(k => k.Key))
{
Console.WriteLine("{0}", lists[element]);
}
const int listSize=6;
列表一=新列表{0,1,2,3,4,5};
列表二=新列表{10,1,9,2,8,3};
列表三=新列表{5,5,5,5,5};
字典列表=新字典()
{
{1,0},
{2,0},
{3,0}
};
for(int i=0;ik[i]);
列出[sortedAtIndex.ElementAt(0)]+;
}
//为了让你知道它是有效的。。。
foreach(lists.OrderByDescending中的var元素(k=>k.Value)
.选择(k=>k.Key))
{
WriteLine(“{0}”,列出[element]);
}
您应该能够使用LINQ和用于IEnumerable
的自定义IComparer来完成此操作
公共类EnumerableDoubleComparer:IComparer
{
公共整数比较(IEnumerable a,IEnumerable b)
{
var counts=a.Select((k,i)=>new{Value=
outerList.Sort(CompareLists);
const int listSize = 6;
List<int> one = new List<int> { 0, 1, 2, 3, 4, 5 };
List<int> two = new List<int> { 10, 1, 9, 2, 8, 3 };
List<int> three = new List<int> { 5, 5, 5, 5, 5, 5 };
Dictionary<List<int>, int> lists = new Dictionary<List<int>, int>()
{
{one, 0},
{two, 0},
{three, 0}
};
for (int i = 0; i < listSize; i++)
{
var sortedAtIndex = lists.Keys.OrderByDescending(k => k[i]);
lists[sortedAtIndex.ElementAt(0)]++;
}
// And to show you that it works...
foreach (var element in lists.OrderByDescending(k => k.Value)
.Select(k => k.Key))
{
Console.WriteLine("{0}", lists[element]);
}
public class EnumerableDoubleComparer : IComparer<IEnumerable<double>>
{
public int Compare( IEnumerable<double> a, IEnumerable<double> b )
{
var counts = a.Select( (k,i) => new { Value = k, Index = i } )
.Join( b.Select( (k,i) => new { Value = k, Index = i } ),
outer => outer.Index,
inner => inner.Index,
(outer,inner) => outer.Value > inner.Value
? "A"
: (inner.Value > outer.Value
? "B"
: "" ) )
.GroupBy( listID => listID )
.Select( g => new { g.Key, Count = g.Count() } );
// you could also use SingleOrDefault on the collection and check for null
var aCount = counts.Where( c => c.Key == "A" )
.Select( c => c.Count )
.SingleOrDefault();
var bCount = counts.Where( c => c.Key == "B" )
.Select( c => c.Count )
.SingleOrDefault();
return aCount - bCount;
}
}
var a = new double[] { 1, 1 };
var b = new double[] { 2, 2 };
var c = new double[] { 3, 3 };
var lists = new List<IEnumerable<double>> { a, c, b };
var ordered = lists.OrderByDescending( l => l, new EnumerableDoubleComparer() );