我想知道如何在C#中高效地检查一个int数组是否是另一个(或相等)的循环排列。
例如,以下数组是循环排列:{1,2,3}
,{2,3,1}
和{3,1,2}
,而{2,1,3}
不是。有什么想法吗?
答案 0 :(得分:1)
以下方法应产生所需的行为:
bool IsCyclicPermutation(int[] a, int[] b) {
if (a == null || b == null || a.Length != b.Length) return false;
for (int i = 0; i < a.Length; i++)
{
if (a[i] == b[0]) // Potential starting point of cycle found
{
bool isCyclic = true;
for (int j = 1; j < b.Length && isCyclic; j++)
{
if (a[(j + i) % a.Length] != b[j]) isCyclic = false;
}
if (isCyclic) return true; // Cycle found
}
}
return false; // No cycles found
}
编辑 如果没有重复的数字,则可以使用以下修改的代码来获得更好的性能:
bool IsCyclicPermutation(int[] a, int[] b) {
if (a == null || b == null || a.Length != b.Length) return false;
for (int i = 0; i < a.Length; i++)
{
if (a[i] == b[0]) // Starting point of potential cycle found
{
bool isCyclic = true;
for (int j = 1; j < b.Length && isCyclic; j++)
{
if (a[(j + i) % a.Length] != b[j]) isCyclic = false;
}
return isCyclic;
}
}
return false; // No cycles found
}
已执行以下测试:
var arr1 = new int[] {1, 2, 3};
var arr2 = new int[] {2, 3, 1};
var arr3 = new int[] {3, 1, 2};
var arr4 = new int[] {2, 1, 3};
IsCyclicPermutation(arr1, arr1); // True
IsCyclicPermutation(arr1, arr2); // True
IsCyclicPermutation(arr1, arr3); // True
IsCyclicPermutation(arr2, arr1); // True
IsCyclicPermutation(arr2, arr2); // True
IsCyclicPermutation(arr2, arr3); // True
IsCyclicPermutation(arr3, arr1); // True
IsCyclicPermutation(arr3, arr2); // True
IsCyclicPermutation(arr3, arr3); // True
IsCyclicPermutation(arr4, arr1); // False
IsCyclicPermutation(arr4, arr2); // False
IsCyclicPermutation(arr4, arr3); // False
关于性能,很难说没有什么可与之进行比较的,尽管我确实相信它是O(n),其中n是输入数组的大小。
答案 1 :(得分:0)
int[] array1 = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
int[] array2 = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
int tmp = array1[0];
int index = Array.IndexOf(array2, tmp);
int n = array1.Length;
for (int i = 1; i < n; i++)
{
if (index + i < array1.Length)
{
if (array1[i] != array2[index+i])
{
Console.WriteLine("Arrays are not equal");
break;
}
}
else
{
if (array1[i] != array2[index + i - n])
{
Console.WriteLine("Arrays are not equal");
break;
}
}
}
我假设数组的长度及其元素相同。上面的代码在O(n)处完成工作。仔细检查索引!
答案 2 :(得分:0)
确定:
div role = "alert" class = "alert alert-#{alert-type}"
button.close[type="button" data-dismiss="alert" aria-hidden="true"]
输出:
1,2,3是2,3,1 True的Ciruclar排列
1,2,3是3,1,2 True的Ciruclar排列
2,3,1是1,2,3 True的Ciruclar排列
2,3,1是3,1,2 True的Ciruclar排列
3,1,2是1,2,3 True的Ciruclar排列
3,1,2是2,3,1 True的Ciruclar排列
2,1,3是1,2,3假的Ciruclar排列
2,1,3是2,3,1假的Ciruclar排列
2,1,3是3,1,2假的Ciruclar排列
答案 3 :(得分:0)
如果您遇到困难的问题,请将其转换为简单的问题,下面的代码使用链表来解决该问题,这不是最佳的性能,但易于理解。
public class SameTest<T>
{
public bool TestCircularArray(IEnumerable<T> array1, IEnumerable<T> array2)
{
if (array1 == null)
throw new ArgumentNullException("array1");
if (array2 == null)
throw new ArgumentNullException("array2");
// if they are the same, the length must be the same
if (array1.Count() != array2.Count())
return false;
// two empty array assume to same
if (!array1.Any())
return true;
// convert array2 to linkedlist
var linkedList = new LinkedList<T>(array2);
LinkedListNode<T> node = null;
foreach (T item1 in array1)
{
// first find the element in link
if (node == null)
{
node = linkedList.Find(item1);
if (node == null)
return false;
continue;
}
node = node.Next;
// reach tail move to head
if (node == null)
node = linkedList.First;
if (!item1.Equals(node.Value))
return false;
}
return true;
}
}
[TestMethod]
public void TestMethod1()
{
int[] array1 = {2, 3, 1};
int[] array2 = {1, 2, 3};
int[] array3 = {2, 1, 3};
var tester = new SameTest<int>();
var result = tester.TestCircularArray(array1, array2);
Assert.AreEqual(true, result);
result = tester.TestCircularArray(array2, array3);
Assert.AreEqual(false, result);
}