【问题标题】:Need help understanding algorithm for longest consecutive item in array需要帮助理解数组中最长连续项的算法
【发布时间】:2020-03-23 07:21:23
【问题描述】:

我得到一个包含二进制值的向量。我需要在整个向量中找到最长的连续连续条纹。这是我无法完全解决的逻辑类型。我可以解决大多数情况,但不是全部,这意味着我的算法有问题。我们甚至可以将问题的方式更改为任何数组中的任何类型的连续值。我试过一个计算正面和反面条纹的问题,但仍然无法解决 10/ 10 个案例。

我认为当条纹从向量的后半部分开始而不是从第一个元素开始的最大条纹开始时,该算法给出了错误的答案。

这是我针对基于二进制值请求条纹的问题的算法。 此外,我了解 2 个迭代器值并不是最有效的,但我想用我的术语简化我的答案。

示例输入: [1,1,0]

样本输出: 2

示例输入 2:[1,1,0,0,0,1,1,1]

样本输出 2:3

void getMaxStreaks(vector<int> arr) {
int largest_streak{0};
int streak_counter{0};

for(int i = 0; i <= arr.size() - 1; i++){
if(arr[i] == 1){
    streak_counter = 1;
}
    for(int j = i + 1; j <= arr.size() -1; j++){
        if(arr[i] == 1 && arr[j] == 1){
            streak_counter++;
        }

        else if(arr[i] == 1 && arr[j] == 0){
            if(streak_counter > largest_streak){
            largest_streak = streak_counter;
            streak_counter = 0;
            }
        }

    }
    if(streak_counter > largest_streak){
        largest_streak = streak_counter;
        streak_counter = 0;
    }
}

【问题讨论】:

  • “我得到了一个包含二进制值的向量”:这很不清楚。你的意思是你有一个 vector&lt;int&gt; 只包含值 0 和 1 ?
  • 还有edit您的问题并显示minimal reproducible example,包括输入示例和预期输出与实际输出
  • 正如你所说的逻辑是完全错误的。连续是连续值。您的代码只是测试单个值。在某个地方,您需要以某种方式针对其前身测试向量值。
  • 我添加了 2 个不同的案例并正确输出。很抱歉不清楚。抱歉,我的意思是在值向量内进行测试。我的大脑可能会因为被这个概念卡住而被烧毁,所以对于不够清晰表示歉意。
  • 这是一种方法。您的代码需要具有布尔变量,如果您当前处于连续状态,则该变量为 true,否则为 false。然后,当您读取 1 时,如果您没有连续,那么您知道您正在开始一个,如果您处于连续状态,您可以将该连续的长度增加一。然后,当您读取 0 并且如果您处于连胜状态,那么您知道您刚刚完成了一个,所以现在您有了刚刚完成的连胜的长度,您可以将其与迄今为止发现的最长连胜进行比较。

标签: c++ algorithm iterator logic


【解决方案1】:

这是一个有点冗长的答案。我相信你可以进一步简化它,但所有的逻辑都在这里。

你做错了很多事情:

  1. 您的数组访问从 1 开始,int i = 1,而不是 0,因此您跳过了数组中的第一个值。
  2. 您可以只写 i
  3. 您不必要地检查数组是否以 i != arr.size() - 1 结束,for 循环将防止这种情况发生。
  4. 由于嵌套的 if 语句,您每次 arr[i] == 1 都会将 streak_counter 增加两次。
  5. 您在 for 循环的每个循环中都将 streak_counter 设置为 0,从而防止您找到超过 1 的条纹。
void streak_checker(vector<int> arr)
{
    int streak_counter{ 0 };
    int largest_streak{ 0 };
    for (int i = 0; i < arr.size(); i++)
    {
        if (arr[i] == 1)
        {
            streak_counter++;
        }
        else
        {
            if (streak_counter > largest_streak)
            {
                largest_streak = streak_counter;
            }
            streak_counter = 0;
        }
    }

    if (streak_counter > largest_streak)
    {
        largest_streak = streak_counter;
    }

    cout << largest_streak;
}

【讨论】:

  • 1:我混合了 2 个解决方案,一个是以前的编辑。我尝试使用一个迭代器变量来处理它,因为 i - 1 将启动条纹检查器,并且我将在向量中移动。抱歉编辑错误。我一直在尝试解决它一个小时...感谢您检查该错误:) 4:啊,我明白为什么它现在开始射击了!我以一种杂乱无章的方式接近它。 5:谢谢你的收获!这是我尝试进行条纹重置计数器的方法之一,但我现在看到了错误。谢谢你:)
  • @SKSam 很高兴我能帮上忙!我了解您的代码在尝试调试时会变得多么荒谬!另外,稍微解释一下代码:当 for 循环结束时,如果最终值为 1,则 streak_counter 将递增,但程序不会检查它是否大于 maximum_streak。因此,需要再进行一次检查以查看当前的连续性是否更大。这就是为什么有 2 个检查实例的原因。我相信这可以做得更好,但这就是我一直解决这个问题的方法。干杯!
【解决方案2】:

您正在寻找的算法基本上是:

maxstart = 0, maxsize = 0                 # Initial maximum to date, zero
                                          # size means it'll be replaced by
                                          # any run of ones.
state = 0                                 # Initial state is "processing zeros",
                                          # meaning first one will start a run and
                                          # correctly initialise that run.

curr = 0                                  # For setting start of a run.
for each bit in bit_collection:           # Process every bit.
    if state == 0 and bit == 1:           # Catch transition zero -> one.
        start = curr, size = 1            # Initialise this run of ones.
        state = 1                         # Change state.
    elif state == 1:                      # Processing ones.
        if bit == 0:                      # Catch transition one -> zero.
            if size > maxsize:            # Replace longest if this one was longer.
                maxstart = start
                maxsize = size
        else:                             # Continuing a run of ones, increase size.
            size += 1
    curr += 1                             # Update index for run starts.

if state == 1:                            # Special handling of final run of ones.
    if size > maxsize:                    # Replace longest if this one is longer.
        maxstart = start
        maxsize = size

这是一个忽略 0 的运行并计算 1 的运行的状态机。在从10 的任何转换(包括集合末尾的“假装”),我们只检查运行是否刚刚完成了之前最长的运行,如果是,则使用这个新的运行作为未来最长。

在这个过程结束时,maxstart 将保存最大运行的起始索引,maxsize 将保存计数。

【讨论】:

  • 谢谢你,我会通读它并融入我自己的想法:)
猜你喜欢
  • 2019-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-20
  • 1970-01-01
  • 2012-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多