Помимо других ответов, вы можете ускорить процесс, создав недорогой хеш, просто построенный из XOR среди всех элементов каждого списка.
Вам не придется заказывать свой список, и все, что вы получите, это int
, который легче и быстрее хранить, чем строки.
Тогда вам нужно только использовать полученный XOR-номер в качестве ключа для Hashtable и проверить его на наличие ключа перед его вставкой.
Если уже существует существующий ключ, только тогда вы сортируете соответствующие списки и сравниваете их.
Вам все равно нужно сравнить их, если вы найдете совпадение, потому что могут быть некоторые столкновения при использовании простого XOR.
Я думаю, думал, что результат будет гораздо быстрее и будет занимать гораздо меньше памяти, чем переупорядочение массивов и преобразование их в строки.
Если бы у вас была собственная реализация List<>
, то вы могли бы построить генерацию ключа XOR внутри него, чтобы он пересчитывался при каждой операции в Списке.
Это сделает процесс проверки дублированных списков еще быстрее.
Код
Ниже приведена первая попытка реализации этого.
Dictionary<int, List<List<int>>> checkHash = new Dictionary<int, List<List<int>>>();
public bool CheckDuplicate(List<int> theList) {
bool isIdentical = false;
int xorkey = 0;
foreach (int v in theList) xorkey ^= v;
List<List<int>> existingLists;
checkHash.TryGetValue(xorkey, out existingLists);
if (existingLists != null) {
// Already in the dictionary. Check each stored list
foreach (List<int> li in existingLists) {
isIdentical = (theList.Count == li.Count);
if (isIdentical) {
// Check all elements
foreach (int v in theList) {
if (!li.Contains(v)) {
isIdentical = false;
break;
}
}
}
if (isIdentical) break;
}
}
if (existingLists == null || !isIdentical) {
// never seen this before, add it
List<List<int>> newList = new List<List<int>>();
newList.Add(theList);
checkHash.Add(xorkey, newList);
}
return isIdentical;
}
Не самый элегантный или самый легкий для чтения на первый взгляд, это скорее «хаккейный», и я даже не уверен, что он работает лучше, чем более элегантная версия от Guffa.
Однако он позаботился о столкновении в ключе XOR, сохранив списки List<int>
в словаре.
Если найден дубликат ключа, мы перебираем каждый ранее сохраненный список, пока не обнаружим несоответствие.
Хорошим моментом в коде является то, что он, вероятно, должен быть настолько быстрым, насколько это возможно в большинстве случаев, и все же быстрее, чем компилирование строк при столкновении.