【问题标题】:Longest Consecutive Sequence in Array C++数组 C++ 中的最长连续序列
【发布时间】:2020-02-06 02:55:03
【问题描述】:

我必须创建一个函数来查找数组中最长的连续整数序列。

数组是这样的:

{1,2,3,4,4,4,5,7,9,10}

注意:跳过序列中的重复数字。

这是我的代码:

int longestSequence(const int arr[], int size)
{
  int currentSeq = 1;//set to 1 because all sequences are at least 1
  int maxSeq;

  for (int i = 1; i < size; i++)
  {
    if (arr[i] == arr[i-1]);//skip repeated numbers

    else if (arr[i-1] == (arr[i] - 1))//check if index is 1 greater than last
    {
      currentSeq++;
    }
    else //if not reset and hold last sequence value as max
      {
        maxSeq = currentSeq;
        currentSeq = 1;
      }
  }
  if (currentSeq > maxSeq) //if the last index of the array was last in the sequence
  {
    maxSeq = currentSeq;
  }

  return maxSeq;
}

我的代码一直为这个数组返回 2,但显然它应该是 5。

任何帮助将不胜感激。

【问题讨论】:

  • 您总是在序列的末尾设置maxSeq。你检查 if 对于循环外的最后一个是否真的更长。
  • @FrançoisAndrieux 感谢您的回复,但是,即使将其移动到循环中,它仍然返回 2。
  • 不,您必须向else 添加条件以检查当前序列是否超过最大值。您还需要初始化maxSeq

标签: c++ arrays


【解决方案1】:

您的数组中有 3 个序列:

  • 1, 2, 3, 4, 4, 4, 5 有 5 个连续数字。
  • 5, 7 不连续,将返回 1。
  • 7, 9 也将返回 1。
  • 9, 10 有 2 个连续,将返回 2 个。

在你的循环中你正在这样做:

for (int i = 1; i < size; i++)
{
    if (arr[i] == arr[i-1]);//skip repeated numbers

    else if (arr[i-1] == (arr[i] - 1))//check if index is 1 greater than last
    {
        currentSeq++;
    }
    else //if not reset and hold last sequence value as max
    {
        maxSeq = currentSeq; // <-- You're resetting your maxSequence even if
                             // currentSeq is smaller.
        currentSeq = 1;
    }
}

如下改变你的循环:

for (int i = 1; i < size; i++)
{
    if (arr[i] == arr[i-1])
        continue; //It is a good practice to skip the rest of the loop's 
                  //checks if you already know you're not gonna need them.
                  //The continue keyword skips only the current iteration of 
                  //the loop and improves intent readability.
    else if (arr[i-1] == (arr[i] - 1))//check if index is 1 greater than last
    {
        currentSeq++;
    }
    else //if not reset and hold last sequence value as max
    {
        currentSeq = 1; //This line stays.
                        //You only want to reset it under these specific conditions.
    }

    if (currentSeq > maxSeq) // Now you'll get the last sequence as well.
        maxSeq = currentSeq;
}

您可以在循环之外删除该检查并直接返回。如果最后一个currentSeq 大于maxSeq,则会正确注册。

此外,当我进行此更改时,我得到了一个编译错误,因为循环内的新if (currentSeq &gt; maxSeq) 试图在设置之前读取maxSeq。所以将maxSeq的声明改为int maxSeq = 0

通过这些更改,我得到了预期值 5。

【讨论】:

  • 感谢您提供如此全面的答案。我进行了更改并获得了预期的输出。我完全忽略了我正在覆盖maxSeq,即使它大于currentSeq
  • 我发现在这种数组的情况下需要在循环外进行检查:{0,1,3,4,5,7,10,11,12,13} 因为maxSeq 不会更新为 4,因为在退出循环之前序列没有被破坏。所以代码返回了3
  • @EdsellJ 你是对的。现在我忽略了它哈哈。重复代码是不理想的。我将更新我的答案,您只需检查并设置一次maxSeq
【解决方案2】:

通过使用您提供的示例数组在调试器中运行您的程序,我确定变量 currentSeq 确实达到了值 5,并且该值 5 正确写入了 maxSeq。但是,在程序的后期,maxSeq 会被值 1 和 2 覆盖。

在覆盖maxSeq 之前,您必须确定它是否已经包含比currentSeq 更高的值。在一种情况下,当您到达数组的末尾时,您已经这样做了。但在其他情况下,您不会这样做。

要使这样的比较起作用,您还必须初始化maxSeq,而不仅仅是currentSeq。否则,maxSeq 可能包含一个非常大的数字并且总是大于currentSeq

【讨论】:

    【解决方案3】:
    #include <iostream>
    
    void Log(int idx, int currentSeq, int maxSeq) {
      printf("current[%d] = %d, max[%d] = %d\n", idx, currentSeq, idx, maxSeq);
    }
    
    int LongestSequence(int* arr, int size) {
      int currentSeq = 1;
      int maxSeq = 1;  // max should be initialized as well
      Log(0, currentSeq, maxSeq);
    
      for (int i = 1; i < size; i++) {
        if (arr[i] == arr[i - 1]) {
        } else if (arr[i - 1] == (arr[i] - 1)) {
          currentSeq++;
        } else {
          currentSeq = 1;
        }
        // maxSeq should be updated in time, otherwise it would be tossed away
        maxSeq = std::max(maxSeq, currentSeq);
        Log(i, currentSeq, maxSeq);
      }
    
      return maxSeq;
    }
    
    int main() {
      int arr[] = {1, 2, 3, 4, 4, 4, 5, 7, 9, 10};
      std::cout << LongestSequence(arr, sizeof(arr) / sizeof(arr[0])) << std::endl;
    }
    

    输出:

    current[0] = 1, max[0] = 1
    current[1] = 2, max[1] = 2
    current[2] = 3, max[2] = 3
    current[3] = 4, max[3] = 4
    current[4] = 4, max[4] = 4
    current[5] = 4, max[5] = 4
    current[6] = 5, max[6] = 5
    current[7] = 1, max[7] = 5
    current[8] = 1, max[8] = 5
    current[9] = 2, max[9] = 5
    5
    

    【讨论】:

    • 感谢您的回答,但我的大脑不知道您在那里做了什么,因为我是&lt;vectors&gt; 的新手并且从未使用过&lt;map&gt;
    • @EdsellJ 你真可爱。我没有在代码中使用vectormap。所以不用担心。
    猜你喜欢
    • 2011-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    相关资源
    最近更新 更多