Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 在保持顺序的同时对循环缓冲区进行分区_Algorithm - Fatal编程技术网

Algorithm 在保持顺序的同时对循环缓冲区进行分区

Algorithm 在保持顺序的同时对循环缓冲区进行分区,algorithm,Algorithm,我有一个自然值为正的循环缓冲区,例如 1 5 4 2 11 7 2 9 我们将把它分成两个连续的部分,同时保持这个顺序。本例中的这两个部分可能是: (4 1 5)和(2 7 9 2 11) (7 9 2 11 4)和(1 5 2) 等等 这个想法是为了保持秩序,并采取两个连续的子序列 现在的问题是对它进行分区,使这些子序列的和彼此接近,也就是说,和之间的差必须最接近于零 在这种情况下,我相信解决方案是:(2 7 9 2)和(11 4 1 5)分别加上和,20和

我有一个自然值为正的循环缓冲区,例如

  1  5
4      2
11     7
  2  9
我们将把它分成两个连续的部分,同时保持这个顺序。本例中的这两个部分可能是:

  • (4 1 5)
    (2 7 9 2 11)
  • (7 9 2 11 4)
    (1 5 2)
  • 等等
这个想法是为了保持秩序,并采取两个连续的子序列

现在的问题是对它进行分区,使这些子序列的和彼此接近,也就是说,和之间的差必须最接近于零

在这种情况下,我相信解决方案是:
(2 7 9 2)
(11 4 1 5)
分别加上和,
20
21

如何以最佳方式执行此操作?

算法:

  • 计算总数

  • 让当前和=0

  • 从任意点的两个指针开始(两个指针从同一点开始)

  • 增加第二个指针,将其传递的数字相加,直到当前总和超过总和的一半

  • 增加第一个指针,减去它传递的数字,直到当前总和小于总和的一半

  • 如果出现以下情况之一,则停止:

    • 第一个指针返回其起始位置,或

    • 最佳总和为总总和的一半的0.5或0(在这种情况下,差值为1或0)

      只有当总和为奇数时,差值才能为1,在这种情况下,差值永远不能为0。(谢谢阿图尔!)

  • 否则,重复步骤3

  • 检查我们在这个过程中得到的所有当前总和,并保留最接近一半的一个,以及得到该总和的分区的索引

    运行时间:

    运行时间将是
    O(n)
    ,因为我们只增加指针,第一个指针只循环一次,第二个指针循环不能超过两次

    示例:

    输入:

      1  5
    4      2
    11     7
      2  9
    
    总数=41

    总和的一半=20.5

    那么,假设我们从1点开始。(我只是把它放在一条直线上,以便于绘制)

    总和=0

    p1 p2
    V  V
     1  5  2  7  9  2  11  4
    
    总和=1

    p1    p2
    V     V
     1  5  2  7  9  2  11  4
    
    总和=6

    p1       p2
    V        V
     1  5  2  7  9  2  11  4
    
    总和=8

    p1          p2
    V           V
     1  5  2  7  9  2  11  4
    
    总和=15

    p1             p2
    V              V
     1  5  2  7  9  2  11  4
    
    总和=24

       p1          p2
       V           V
     1  5  2  7  9  2  11  4
    
    总和=23

          p1       p2
          V        V
     1  5  2  7  9  2  11  4
    
    总和=18

          p1          p2
          V           V
     1  5  2  7  9  2  11  4
    
    总和=20

    这里的和(20)是总和(20.5)的一半的0.5,所以我们可以停止

    上述内容对应于
    (11 4 1 5)(2 7 9 2)
    ,两者之和相差
    1

    算法:

  • 计算总数

  • 让当前和=0

  • 从任意点的两个指针开始(两个指针从同一点开始)

  • 增加第二个指针,将其传递的数字相加,直到当前总和超过总和的一半

  • 增加第一个指针,减去它传递的数字,直到当前总和小于总和的一半

  • 如果出现以下情况之一,则停止:

    • 第一个指针返回其起始位置,或

    • 最佳总和为总总和的一半的0.5或0(在这种情况下,差值为1或0)

      只有当总和为奇数时,差值才能为1,在这种情况下,差值永远不能为0。(谢谢阿图尔!)

  • 否则,重复步骤3

  • 检查我们在这个过程中得到的所有当前总和,并保留最接近一半的一个,以及得到该总和的分区的索引

    运行时间:

    运行时间将是
    O(n)
    ,因为我们只增加指针,第一个指针只循环一次,第二个指针循环不能超过两次

    示例:

    输入:

      1  5
    4      2
    11     7
      2  9
    
    总数=41

    总和的一半=20.5

    那么,假设我们从1点开始。(我只是把它放在一条直线上,以便于绘制)

    总和=0

    p1 p2
    V  V
     1  5  2  7  9  2  11  4
    
    总和=1

    p1    p2
    V     V
     1  5  2  7  9  2  11  4
    
    总和=6

    p1       p2
    V        V
     1  5  2  7  9  2  11  4
    
    总和=8

    p1          p2
    V           V
     1  5  2  7  9  2  11  4
    
    总和=15

    p1             p2
    V              V
     1  5  2  7  9  2  11  4
    
    总和=24

       p1          p2
       V           V
     1  5  2  7  9  2  11  4
    
    总和=23

          p1       p2
          V        V
     1  5  2  7  9  2  11  4
    
    总和=18

          p1          p2
          V           V
     1  5  2  7  9  2  11  4
    
    总和=20

    这里的和(20)是总和(20.5)的一半的0.5,所以我们可以停止


    上述对应于
    (11 4 1 5)(2 7 9 2)
    ,在计算成本或只是最优解的意义上,两者之和的差异为
    1

    。@arturgrzesiak计算成本。我们可以用天真的方法在二次时间内找到最优解,对吗?:)应该是线性的-参见Dukelings的“计算成本意义上的后优化”或“仅最优解”?@arturgrzesiak计算成本。我们可以用天真的方法在二次时间内找到最优解,对吗?:)应该是线性的-参见Dukelings的post+1。我能想到的唯一改进是在差为零(如果总和为偶数)或一(如果总和为奇数)时停止算法。@arturgrzesiak谢谢!已编辑。+1我能想到的唯一改进是在差为零(如果总和为偶数)或一(如果总和为奇数)时停止算法。@arturgrzesiak谢谢!编辑。