检查两个数组中的C#中的循环置换

时间:2019-03-08 00:02:02

标签: c#

我想知道如何在C#中高效地检查一个int数组是否是另一个(或相等)的循环排列。

例如,以下数组是循环排列:{1,2,3}{2,3,1}{3,1,2},而{2,1,3}不是。有什么想法吗?

4 个答案:

答案 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)

确定:

DotNetFiddle Working Example

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);
}