我想编写一个程序,该程序在整数数组中找到最长的相等元素序列。如果存在几个最长的序列,我们应该打印最左边的。例如
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));
}
如果您能向我解释如何做,我将不胜感激。
答案 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
以下语句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();
}
}