我有一个列表,如果包含按顺序排列的所有数字,则需要将其排序:
手动设置它们似乎并不可行。
我知道如何对列表进行升序或降序排序,但是模数为4使我很头疼。
模数为4是由于此链接到网格上的节点邻居
我不知道它们最初是按什么顺序排列的,因为它是随机的,并且每次都会更改-网格连接的过程生成
我不想要一个新列表,我只想简单地重新排列当前列表。
清单计数3:
0、1、2
一二三
2 3 0
3 0 1
if (acceptedIndicies.Contains(0) && acceptedIndicies.Contains(1) && acceptedIndicies.Contains(2)) // Top-Right-Down
{
// Order List in the sequence
acceptedIndicies[0] = 0;
acceptedIndicies[1] = 1;
acceptedIndicies[2] = 2;
}
else if (acceptedIndicies.Contains(1) && acceptedIndicies.Contains(2) && acceptedIndicies.Contains(3)) // Right-Down-Left
{
// Order List in the sequence
acceptedIndicies[0] = 1;
acceptedIndicies[1] = 2;
acceptedIndicies[2] = 3;
}
else if (acceptedIndicies.Contains(2) && acceptedIndicies.Contains(3) && acceptedIndicies.Contains(0)) // Down-Left-Top
{
// Order List in the sequence
acceptedIndicies[0] = 2;
acceptedIndicies[1] = 3;
acceptedIndicies[2] = 0;
}
else if (acceptedIndicies.Contains(3) && acceptedIndicies.Contains(0) && acceptedIndicies.Contains(1)) // Left-Top-Right
{
// Order List in the sequence
acceptedIndicies[0] = 3;
acceptedIndicies[1] = 0;
acceptedIndicies[2] = 1;
}
清单计数2:
0,1
一二
2 3
3,0
if (acceptedIndicies.Contains(0) && acceptedIndicies.Contains(1))
{
// Order List in the sequence
acceptedIndicies[0] = 0;
acceptedIndicies[1] = 1;
}
else if (acceptedIndicies.Contains(1) && acceptedIndicies.Contains(2))
{
// Order List in the sequence
acceptedIndicies[0] = 1;
acceptedIndicies[1] = 2;
}
else if (acceptedIndicies.Contains(2) && acceptedIndicies.Contains(3))
{
// Order List in the sequence
acceptedIndicies[0] = 2;
acceptedIndicies[1] = 3;
}
else if (acceptedIndicies.Contains(3) && acceptedIndicies.Contains(0))
{
// Order List in the sequence
acceptedIndicies[0] = 3;
acceptedIndicies[1] = 0;
}
最佳答案
您可以执行以下操作:
建立有效的模数序列。这很简单:
var modulusSequence = Enumerable.Range(0, modulus);
现在,您需要一种生成给定模数和长度的所有有效模数序列的方法。这也很容易,只需要向左或向右移动一个有效序列总共
modulus
次,我们碰巧知道每个新移位序列的前n个元素都是:private static IEnumerable<int> ShiftLeft(IEnumerable<int> sequence)
{
if (!sequence.Any())
yield break;
foreach (var i in sequence.Skip(1))
{
yield return i;
}
yield return sequence.First();
}
private static IEnumerable<IEnumerable<int>> getAllModulusSequences(int modulus, int length)
{
var sequence = Enumerable.Range(0, modulus);
for (var i = 0; i < modulus; i++)
{
yield return sequence.Take(length);
sequence = ShiftLeft(sequence);
}
}
现在,您只需要检查给定序列是否包含有效序列的所有元素(请注意,这样做是不正确的,因为如果给定序列包含重复项,您可能会得到假阳性结果)。如果是这样,则返回有效序列。
我确实注意到,我没有订购您的清单,而是返回了一个新的清单,如果序列无效,则返回
null
。public static IList<int> GetOrderedSequence(IList<int> sequence, int modulus)
{
if (modulus < sequence.Count)
throw new ArgumentOutOfRangeException(nameof(sequence), "Sequence can not contain more elements than specified modulus.");
foreach (var validSequence in getAllModulusSequences(modulus, sequence.Count))
{
if (validSequence.All(item => sequence.Contains(item)))
return validSequence.ToList();
}
return null;
}
这比您的方法更快/更有效吗?可能不会。漂亮吗?我认为是这样,但值得商.。它更灵活吗?哦,是的!
如果您完全确定只需要检查模数为
2
的3
和4
长序列,则可以保留代码。如果没有,请实施一种通用解决方案,例如我向您展示的解决方案。