简单的情况.我有一个列表列表,几乎像表格一样,我试图找出是否有任何列表重复.
例:
List<List<int>> list = new List<List<int>>(){
new List<int>() {0 ,1 ,2, 3, 4, 5, 6 },
new List<int>() {0 ,1 ,2, 3, 4, 5, 6 },
new List<int>() {0 ,1 ,4, 2, 4, 5, 6 },
new List<int>() {0 ,3 ,2, 5, 1, 6, 4 }
};
Run Code Online (Sandbox Code Playgroud)
我想知道总共有4个项目,其中2个是重复项目.我正在考虑做类似SQL校验和的事情,但我不知道是否有更好/更简单的方法.
我关心性能,我关心订购.
可能有用的其他信息
让我们试着获得最佳表现.如果n是列表的数量而m是列表的长度,那么我们可以得到O(n m + n logn + n)加上一些哈希码的概率对于不同的列表是相等的.
主要步骤:
*这是重要的一步.对于simlicity你可以将hash hash as = ... ^(list [i] << i)^(list [i + 1] <<(i + 1))
编辑那些认为PLINQ可以提升这个东西的人,但不是好的algorythm.PLINQ也可以在这里添加,因为所有步骤都可以轻松并行化.
我的代码:
static public void Main()
{
List<List<int>> list = new List<List<int>>(){
new List<int>() {0 ,1 ,2, 3, 4, 5, 6 },
new List<int>() {0 ,1 ,2, 3, 4, 5, 6 },
new List<int>() {0 ,1 ,4, 2, 4, 5, 6 },
new List<int>() {0 ,3 ,2, 5, 1, 6, 4 }
};
var hashList = list.Select((l, ind) =>
{
uint hash = 0;
for (int i = 0; i < l.Count; i++)
{
uint el = (uint)l[i];
hash ^= (el << i) | (el >> (32 - i));
}
return new {hash, ind};
}).OrderBy(l => l.hash).ToList();
//hashList.Sort();
uint prevHash = hashList[0].hash;
int firstInd = 0;
for (int i = 1; i <= hashList.Count; i++)
{
if (i == hashList.Count || hashList[i].hash != prevHash)
{
for (int n = firstInd; n < i; n++)
for (int m = n + 1; m < i; m++)
{
List<int> x = list[hashList[n].ind];
List<int> y = list[hashList[m].ind];
if (x.Count == y.Count && x.SequenceEqual(y))
Console.WriteLine("Dupes: {0} and {1}", hashList[n].ind, hashList[m].ind);
}
}
if (i == hashList.Count)
break;
if (hashList[i].hash != prevHash)
{
firstInd = i;
prevHash = hashList[i].hash;
}
}
}
Run Code Online (Sandbox Code Playgroud)