猿问

如何根据不完整的标准进行排序?

首先,我尝试将自己的函数传递给Array.sort,但排序不正确。注意结果中的'c'before'a'是如何出现的,即使案例if (b == 'a' && a == 'c')处理正确。


这些数据只是举例。我的实际数据不按字母顺序排序。它必须使用a_before_b和b_before_a函数中说明的逻辑。


由于我只有确定某些(不是全部)元素对的相对顺序的条件,因此可能存在多个有效的元素顺序。我只需要生成任何有效的顺序,其中有效的方式不与我的任何条件(在a_before_b和b_before_a函数中定义)相矛盾。


const sorted = ['a', 'b', 'c', 'd']; // I do NOT have access to this

const unsorted = ['c', 'd', 'a', 'b'];


const a_before_b = (a, b) => {

  if (a == 'a' && b == 'd') return true;

  if (a == 'b' && b == 'c') return true;

}


const b_before_a = (a, b) => {

  if (b == 'a' && a == 'c') return true;

  if (b == 'b' && a == 'c') return true;

}


const mySortingFunction = (a, b) => {

  if (a_before_b(a, b)) return -1;

  if (b_before_a(a, b)) return 1;

  return 0;

}


// doesn't produce correct sorting 

console.log(unsorted.sort(mySortingFunction)); // [ 'c', 'a', 'd', 'b' ]

然后我尝试从头开始编写自己的排序。但是进入了死循环,不知道为什么。


const sorted = ['a', 'b', 'c', 'd'];

const unsorted = ['c', 'd', 'a', 'b'];


const a_before_b = (a, b) => {

  if (a == 'a' && b == 'd') return true;

  if (a == 'b' && b == 'c') return true;

}


const b_before_a = (a, b) => {

  if (b == 'a' && a == 'c') return true;

  if (b == 'b' && a == 'c') return true;

}


const findAnUnsortedElement = array => {

  for (let [i, element] of Object.entries(array)) {

    i = +i;

    const a = element;

    const b = array[i + 1];

    if (b === undefined) return 'SORTING_COMPLETE';

    if (!a_before_b(a, b)) console.log(a, 'should not be before', b);

    if (b_before_a(a, b)) console.log(b, 'should be before', a);

    if (!a_before_b(a, b) || b_before_a(a, b)) return a;

  }

}


// from w3schools

function move(arr, old_index, new_index) {

  while (old_index < 0) {

    old_index += arr.length;

  }

  while (new_index < 0) {

    new_index += arr.length;

  }

  if (new_index >= arr.length) {

    var k = new_index - arr.length;

    while ((k--) + 1) {

      arr.push(undefined);

    }

  }

  arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);

  return arr;

}



慕侠2389804
浏览 94回答 3
3回答

蓝山帝景

const&nbsp;unsorted&nbsp;=&nbsp;['c',&nbsp;'d',&nbsp;'a',&nbsp;'b']; const&nbsp;sorted&nbsp;=&nbsp;unsorted.sort();它应该工作 我不确定你的问题是什么。

犯罪嫌疑人X

我之前给出的答案中的算法(您(首先)接受了该算法)实际上是基于启发式算法。为了保证排序后的输出没有任何违规,您可以将此问题视为图形问题。只要两个值可以进行比较true(使用任一比较器函数),那么该对就代表图中的一条边。如果顺序一致,那么一定有一个值是其他值中最小的,否则就会有一个循环。因此,有了这些知识,我们就可以为图中的每个节点确定到这样一个最小节点的最长路径有多长。当您找到到此类最小节点的最长距离时,您可以使用该路径的长度作为绝对顺序指示。这是一个实现:class Node {&nbsp; &nbsp; constructor(value) {&nbsp; &nbsp; &nbsp; &nbsp; this.value = value;&nbsp; &nbsp; &nbsp; &nbsp; this.prev = new Set;&nbsp; &nbsp; &nbsp; &nbsp; this.order = 0; // No order yet&nbsp; &nbsp; }&nbsp; &nbsp; orderWith(other) {&nbsp; &nbsp; &nbsp; &nbsp; if (other === this) return;&nbsp; &nbsp; &nbsp; &nbsp; if (a_before_b(this.value, other.value) || b_before_a(other.value, this.value)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; other.prev.add(this);&nbsp; &nbsp; &nbsp; &nbsp; } else if (a_before_b(other.value, this.value) || b_before_a(this.value, other.value)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.prev.add(other);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; setOrder(path = new Set) {&nbsp; &nbsp; &nbsp; &nbsp; // Use recursion to find length of longest path to "least" node.&nbsp; &nbsp; &nbsp; &nbsp; if (this.order) return; // already done&nbsp; &nbsp; &nbsp; &nbsp; if (path.has(this)) throw "cycle detected";&nbsp; &nbsp; &nbsp; &nbsp; let order = 1;&nbsp; &nbsp; &nbsp; &nbsp; for (let prev of this.prev) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prev.setOrder(path.add(this));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; order = Math.max(order, prev.order + 1);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; this.order = order; // If order is 1, it is a "least" node&nbsp; &nbsp; }}const a_before_b = (a, b) => {&nbsp; if (a == 'a' && b == 'd') return true;&nbsp; if (a == 'b' && b == 'c') return true;}const b_before_a = (a, b) => {&nbsp; if (b == 'a' && a == 'c') return true;&nbsp; if (b == 'b' && a == 'c') return true;}function mySort(arr) {&nbsp; &nbsp; // Create a graph: first the nodes&nbsp; &nbsp; let nodes = {}; // keyed by values in arr&nbsp; &nbsp; for (let value of arr) nodes[value] = nodes[value] || new Node(value);&nbsp; &nbsp; // Then the edges...&nbsp; &nbsp; for (let i = 0; i < arr.length; i++) {&nbsp; &nbsp; &nbsp; &nbsp; for (let j = i+1; j < arr.length; j++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nodes[arr[i]].orderWith(nodes[arr[j]]);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; // Set absolute order, using the longest path from a node to a "least" node.&nbsp; &nbsp; for (let node of Object.values(nodes)) node.setOrder();&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; // Sort array by order:&nbsp; &nbsp; return arr.sort((a, b) => nodes[a].order - nodes[b].order);}const sorted = ['a', 'b', 'c', 'd'];const unsorted = ['c', 'd', 'a', 'b'];console.log(mySort(unsorted));

小唯快跑啊

也许是这样的const sorted = ['a', 'b', 'c', 'd']; // I do NOT have access to thisconst unsorted = ['c', 'd', 'a', 'b'];const a_before_b = (a, b) => {&nbsp; if (a == 'a' && b == 'd') return true;&nbsp; if (a == 'b' && b == 'c') return true;&nbsp; if (a == 'a' && b == 'c') return true;}const b_before_a = (a, b) => {&nbsp; if (b == 'a' && a == 'c') return true;&nbsp; if (b == 'b' && a == 'c') return true;}const mySortingFunction = (a, b) => {&nbsp; if (a_before_b(a, b)) return -1;&nbsp; if (b_before_a(a, b)) return 1;&nbsp; return 0;}// doesn't produce correct sorting&nbsp;console.log(unsorted.sort(mySortingFunction));
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答