【问题标题】:How to rearrange an array by indices array (proof)?如何通过索引数组(证明)重新排列数组?
【发布时间】:2016-06-09 10:39:16
【问题描述】:

给定一个数组 arr 和一个索引数组 ind,以下算法会在原地重新排列 arr 以满足给定的索引:

function swap(arr, i, k) {
  var temp = arr[i];
  arr[i] = arr[k];
  arr[k] = temp;
}

function rearrange(arr, ind) {
  for (var i = 0, len = arr.length; i < len; i++) {
    if (ind[i] !== i) {
      swap(arr, i, ind[i]);
      swap(ind, i, ind[i]);
    }
  }
}

例如:

var arr = ["A", "B", "C", "D", "E", "F"];
var ind = [ 4,   0,   5,   2,   1,   3 ];

rearrange(arr, ind);

console.log(arr); // => ["B", "E", "D", "F", "A", "C"]

证明算法有效的最有说服力的方法是什么?

【问题讨论】:

  • 写一堆测试用例,证明通过了...?!
  • 为什么你认为这个算法首先有效?基于索引的输出不应该是["E", "A", "F", "C", "B", "D"]吗?
  • @gurvinder372 ...?为什么?
  • @deceze 除非我错过了什么,否则按照[4, 0, 5, 2, 1, 3] 重新排列["A", "B", "C", "D", "E", "F"] 应该给["E", "A", "F", "C", "B", "D"] 对吗?由于E 位于第四个索引处,A 位于第 0 个索引处..?
  • @gurvinder372 不确定您在那里应用什么逻辑......第二个数组似乎包含第一个数组中相同键值的所需索引。 arr[0] 应该转到索引ind[0],即4,这意味着“A”应该转到位置4

标签: javascript arrays algorithm


【解决方案1】:

这个算法不行,举个反例就够了:

var arr = ["A", "B", "C", "D"];
var ind = [  2,   3,   1,   0];

rearrange(arr, ind);
console.log(arr); // => ["C", "D", "A", "B"]

一个可行的替代方案可能是

function swap(arr, i, k) {
  var temp = arr[i];
  arr[i] = arr[k];
  arr[k] = temp;
}

function rearrange(arr, ind) {
  for (var i = 0, len = arr.length; i < len; i++) {
    if (ind[i] !== i) {
      swap(arr, i, ind[i]);
      swap(ind, i, ind[i]);
      if (ind[i] < i) {
        i = ind[i]-1;
      }
    }
  }
}

【讨论】:

  • 哦,哇!非常感谢您提供一个简单的反例!
  • 我创建了一个new question。您可能想在此处添加您的建议。
猜你喜欢
  • 2015-07-23
  • 1970-01-01
  • 2014-11-29
  • 2017-04-08
  • 2015-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-23
相关资源
最近更新 更多