如何找到整数数组中相等元素的最长序列?

时间:2019-02-10 20:16:41

标签: c# arrays

我想编写一个程序,该程序在整数数组中找到最长的相等元素序列。如果存在几个最长的序列,我们应该打印最左边的。例如

Input: 0 1 1 5 2 2 6 3 3 
Output: 1 1

我知道我的代码无法正常工作,但是我不知道如何解决它。我应该只使用数组解决问题,因为我不知道如何使用列表。

int[] numbers = Console.ReadLine().Split().Select(int.Parse).ToArray();

        for (int i = 0; i < numbers.Length; i++)
        {
            int[] currentSequenceOfEqualElements = new int[numbers.Length];
            for (int j = i + 1; j < numbers.Length; j++)
            {
                if (numbers[i] == numbers[j])
                {
                    if (currentSequenceOfEqualElements[0] == 0)
                    {
                        currentSequenceOfEqualElements[0] = numbers[i];
                        currentSequenceOfEqualElements[1] = numbers[i];
                    }
                    else
                    {
                        currentSequenceOfEqualElements[i + 2] = numbers[i];
                    }
                }
                else
                {
                    break;
                }
            }
            Console.WriteLine(string.Join(' ', currentSequenceOfEqualElements));
        }

如果您能向我解释如何做,我将不胜感激。

3 个答案:

答案 0 :(得分:3)

这是mjwills建议的使用MoreLinq库(https://morelinq.github.io/)的解决方案。 一旦您习惯了linq和morelinq方法,这些代码比带有嵌套循环和if的自定义算法更容易理解。

        var numbers = new int[]{ 0, 1, 1, 5, 2, 2, 6, 3, 3};
        var result = numbers.GroupAdjacent(x => x)
                       .MaxBy(x => x.Count())
                       .FirstOrDefault();

        foreach (var i in result)
        {
            Console.Write($"{i} ");
        } 

答案 1 :(得分:1)

这是一个简单的解决方案,仅使用循环而不使用linq。它应该很好并且易于理解。

int[] numbers = new[] { 0, 1, 1, 5, 2, 2, 6, 3, 3 };

// Some variables to keep track of the sequence we're currently looking
// at, and the longest sequence we've found so far. We're going to start
// the loop at the 2nd number, so we'll initialize these as if we've
// already processed the first number (which is 0, so we've seen the
// first number of a sequence of 0's).        

// Number of numbers in the current sequence
int count = 1;
// Number which is part of the longest sequence so faar
int longestNum = numbers[0];
// Number of numbers in the longest sequence we've seen so far
int longestCount = 1;

for (int i = 1; i < numbers.Length; i++)
{
    // We're starting a new sequence
    if (numbers[i] != numbers[i-1])
    {
        count = 0;
    }

    count++;
    // Have we just found a new longest sequence?
    if (count > longestCount)
    {
        longestCount = count;
        longestNum = numbers[i];
    }
}

// longestNum = 1 and longestCount = 2 (because the longest sequence
// had 2 1's in it). Turn this into the string "1 1".
Console.WriteLine(
    string.Join(" ", Enumerable.Repeat(longestNum, longestCount)));

// If you wanted to end up with an array containing [1, 1], then:
int[] result = new int[longestCount];
Array.Fill(result, longestNum);

答案 2 :(得分:1)

我将为您的问题举例说明递归答案,下面是代码,我保留了一些if-else语句,它们不需要使用它们,但至少代码显示了这一想法。 该代码具有应公开的基本方法和繁重的私有递归方法。最长的序列是空数组(列表)

 var longSequenceEqualElem = new List<int>();

稍后,您通过所有递归调用传递数组的所有元素以继续查询位置,pos参数指示递归的位置级别。

if(pos sequence中应该是最长的位置即可。

以下语句if (sequence.Contains(elems[pos]))表示您在位置pos上发现了与序列相同的数字,因此可以将其添加到序列中,并使用相邻位置(pos + 1)调用递归 如果位置pos中的元素不是您拥有的序列的一部分,那么您需要使用包含elems [pos]的新序列调用递归,然后将该递归调用的结果与序列进行比较,以查看其中的哪个是最长的。 希望这会有所帮助

    class Program
    {
        static void Main(string[] args)
        {
            var elemts = new int[] { 0, 1, 1, 5, 2, 2, 6, 3, 3 };

            var result = LongestSequence(elemts);

            foreach (var i in result)
            {
                Console.Write(i + "\t");
            }

            Console.ReadLine();
        }

        public static int[] LongestSequence(int[] elems)
        {
            var longSequenceEqualElem = new List<int>();
            return LongestSequenceRec(elems, longSequenceEqualElem, 0);
        }

        private static int[] LongestSequenceRec(int[] elems, List<int> sequence, int pos)
        {
            if (pos < elems.Length)
            {
                if (sequence.Contains(elems[pos]))
                {
                    sequence.Add(elems[pos]);
                    return LongestSequenceRec(elems, sequence, pos + 1);
                }
                else
                {
                    var newSeq = LongestSequenceRec(elems, new List<int> { elems[pos] }, pos + 1);
                    return (newSeq.Length > sequence.Count) ? newSeq.ToArray() : sequence.ToArray();
                }
            }
            return sequence.ToArray();
        }
    }