2

2 つのリスト間の遷移をアニメーション化するために、記事の 2 つのリスト間の変更を取得しようとしています。記事は、追加、削除、または移動できます (入れ替えはできません)。

ただし、一部の記事は移動できず、各トランジションで他のすべての記事をそれらの記事の下に移動する必要があります。

たとえば、各数字が記事 ID を表し、太字が不動の記事を表す場合、[1, 2 , 3, 4 , 5, 6] は [ 2 , 4 , 1, 6, 7] になる可能性があります。

必要な変更を行う必要があります。たとえば、この場合は次のようになります。

  • 4 の後に 1 を移動
  • 削除 5
  • 6の後に7を足す

私は差分アルゴリズムを使用していますが、動かせないアイテムを理解していないため、次のように提案される場合があります。

  • 2を先頭に移動
  • 2 の後に 4 を移動
  • 削除 5
  • 6の後に7を足す

いろいろ試してみましたが、確実に動作させることができません。

4

2 に答える 2

2

移動できないアイテムを左に 3 つ移動することは、隣にある 3 つの移動可能なアイテムを 1 つ右に移動することと同じです。現在の差分アルゴリズムを使用しますが、移動できないアイテムを移動したい場合は、代わりにその隣のアイテムに切り替えます。


アップデート。記事ごとに複数の動きがありません。

Transformations:

1. Remove numbers that are not in the second list (for each item n if not in_list(final_list) then say(n removed)).
   [1 2* 4* 5 6] // say("remove 3")
   [1 2* 4* 6]   // say("remove 5")       
2. Make an empty list size of the final list.
   [_ _ _ _ _]
3. Prefill it with immovable numbers in their final positions.
   [2* 4* _ _ _]
4. Loop through movable items from the first list moving them to their final positions
   [2* 4* 1 _ _] // say("move 1 after 4")
   [2* 4* 1 6 _] // say("move 6 after 1")
5. Add new items
   [2* 4* 1 6 7] // say("add 7 after 6")

解いてて楽しい問題でした!

于 2011-02-20T19:22:17.157 に答える
1

アレクセイのおかげで、最終的なコードは次のとおりです。

$immovable = array(2);
$current = array(1,2,8,3,4,5,6);
$new = array(2,7,6,5,4,3,1);

$additions = $additionsCopy = array_diff($new, $current);
foreach($additions as $key => $addition) {
  $after = array_key($new, $addition)-1;
  $additions[$key] = array(
    'value' => $addition, 
    'after' => ($after < 0 ? 0 : $new[$after])
  );
}
for($key = 0; $key < count($new); $key++) {
  if(in_array($new[$key], $additionsCopy)) 
    $new = array_remove($new, $key--);
}

$removals = array_diff($current, $new);
for($key = 0; $key < count($current); $key++) {
  if(in_array($current[$key], $removals)) 
    $current = array_remove($current, $key--);
}

$lastImmovable = -1;
foreach($new as $key => $item) if(in_array($item, $immovable)) 
  $lastImmovable = $key;

$prev = $lastImmovable < 0 ? 0 : $new[$lastImmovable];
foreach($new as $key => $item) if (!in_array($item, $immovable)) {
  $moves[] = array('value' => $item, 'after' =>$prev);
  $prev = $item;
}

この時点で$removals、実行でき$movesます。$additions

于 2011-02-20T20:15:28.280 に答える