Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.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
Sorting 使用多个订单条件重新排序项目_Sorting - Fatal编程技术网

Sorting 使用多个订单条件重新排序项目

Sorting 使用多个订单条件重新排序项目,sorting,Sorting,场景: 照片列表 每张照片都有以下属性 id 序列号 main\u photo\u位 第一张照片的main\u photo\u位设置为1(所有其他照片都是0) 照片按序列号排序(任意) 主照片不一定具有最低的序列号(排序前) 见下表: id, sequence_number, main_photo_bit 1 10 1 2 5 0 3 20

场景

  • 照片列表
  • 每张照片都有以下属性
    • id
    • 序列号
    • main\u photo\u位
  • 第一张照片的
    main\u photo\u位设置为
    1
    (所有其他照片都是
    0
  • 照片按序列号排序(任意)
  • 主照片不一定具有最低的序列号(排序前)
见下表:

id, sequence_number, main_photo_bit
1   10               1             
2    5               0             
3   20               0             
现在,您需要通过更改序列号和主照片位来更改顺序

排序后的要求:

  • 第一张照片的序列号未更改
  • 第一张照片的序列号是最低的
  • 尽可能少的变化
示例:

示例#1(第二张照片位于第一个位置):

事情是这样的:

  • id 1:新的
    序列号
    主照片位
    设置为
    0
  • id 2:旧的第一张照片(id 2)
    序列号
    主照片位
    设置为
    1
  • id 3:什么也没发生
示例2(从第三张照片到第一张照片):

事情是这样的:

  • id 1:新的
    序列号
    大于第一张照片和
    主照片位
    0
  • id 2:新的
    序列号
    大于新生成的第二个
    序列号
  • id 3:旧的第一张照片
    序列号
    主照片位
    设置为
    1
计算保存新订单所需步骤的最佳方法是什么?

编辑:
我希望尽可能少的更新是因为我想将其同步到外部服务,这是一项非常昂贵的操作。
我已经得到了该算法的一个工作原型,但在一些边缘情况下它失败了。因此,我想知道是否有其他(更好的)方法来解决这个问题,而不是修补它(这可能会奏效,但会变得比现在更复杂)。

在我的版本中(简而言之),它订购照片(更改序列号),并交换主照片位,但这并不足以解决所有情况。

据我所知,一个好的解决方案不仅可以最大限度地减少更改(因为更新是一项代价高昂的操作),但也要尽量减少未来的变化,因为越来越多的照片被重新排序。我首先添加一个临时字段
dirty
,以指示行是否必须更改:

id, sequence_number, main_photo_bit, dirty
 1         10               1        false
 2          5               0        false
 3         20               0        false
 4         30               0        false
 5         31               0        false
 6         33               0        false
如果有
序列号
小于第一个的行,它们肯定必须更改(要么获得更高的数字,要么成为第一个)。让我们将它们标记为脏的:

id, sequence_number, main_photo_bit, dirty
 2          5               0        true
(如果第一个序列号是否最低并不重要,请跳过此步骤)

现在让我们看看照片列表,因为它们应该出现在结果中(根据问题,从任何地方到任何地方,只有一张照片改变了位置)。粗体的脏的:

[1,2,3,4,5,6]#原始订单

[21,3,4,5,6]#示例1:从第二名到第一名

[312,4,5,6]#示例2:第3名到第1名

[1,2,4,3,5,6]#示例3:第三至第四名

[1,32,4,5,6]#示例4:第三至第二名

首先要做的是确保第一个元素的序列号最低。如果它没有改变位置,那么根据定义它已经改变了,否则旧的第一个应该被标记为脏的,清除它的
main\u photo\u位
,新的应该接收这些值到它自己

此时,第一个元素应该有一个固定的序列号,每个脏元素的值都可以随意更改(因为它无论如何都必须更改,所以最好更改为有用的值)。在继续之前,我们必须确保只有更改脏行才能解决问题,或者如果更多行也需要脏行,则必须确保有可能解决问题。这只是一个确定每对干净行之间的间隔是否足够大以适应它们之间脏行的数量的问题:

[10, D, 20, 30, 31, 33]   # Original ordering (the first is dirty, but fixed)

[10, D, 20, 30, 31, 33]   # Example 1: 2nd to 1st place (ok: 10 < ? < 20)
[10, D, D, 30, 31, 33]    # Example 2: 3rd to 1st place (ok: 10 < ? < ? < 30)
[10, D, 30, D, 31, 33]    # Example 3: 3rd to 4th place (NOT OK: 30 < ? < 31)
  [10, D, 30, D, D, 33]   #   must mark 5th as dirty too (ok: 30 < ? < ? < 33)
[10, D, D, 30, 31, 33]    # Example 4: 3rd to 2nd place (ok)
[10,D,20,30,31,33]#原始订单(第一个是脏的,但已修复)
[10,D,20,30,31,33]#示例1:第二至第一名(ok:10<?<20)
[10,D,D,30,31,33]#示例2:第三名到第一名(确定:10<30)
[10,D,30,D,31,33]#示例3:第三至第四名(不合格:30<?<31)
[10,D,30,D,D,33]#必须将第五个标记也标记为脏(正常:30<?<?<?<33)
[10,D,D,30,31,33]#示例4:第三到第二名(ok)
现在只需为脏行分配新的
序列号。一个天真的解决方案是只增加前一个,但更好的方法是将它们设置为尽可能等距的。通过这种方式,未来的重新排序需要更少的更改的可能性更大(换句话说,为了避免像示例3这样的问题,因为一些
序列号
s彼此太近,所以必须更新比需要更多的行):

[strong>10
15,20,30,31,33]#示例1:从第二名到第一名

[101623,30,31,33]#示例2:第三名到第一名

[10,20,30,3132,33]#示例3:第三至第四名

[10,16id, sequence_number, main_photo_bit, dirty 2 5 0 true
[10, D, 20, 30, 31, 33]   # Original ordering (the first is dirty, but fixed)

[10, D, 20, 30, 31, 33]   # Example 1: 2nd to 1st place (ok: 10 < ? < 20)
[10, D, D, 30, 31, 33]    # Example 2: 3rd to 1st place (ok: 10 < ? < ? < 30)
[10, D, 30, D, 31, 33]    # Example 3: 3rd to 4th place (NOT OK: 30 < ? < 31)
  [10, D, 30, D, D, 33]   #   must mark 5th as dirty too (ok: 30 < ? < ? < 33)
[10, D, D, 30, 31, 33]    # Example 4: 3rd to 2nd place (ok)
id      next
1       3
2       1
3       
id      next
1       
2       1
3       2