优先级队列方法的字符串排序

时间:2017-01-04 17:00:00

标签: javascript node.js sorting

我在使用优先级队列方法排序字符串时遇到问题。这是我排序的字符串键的一个例子:

[ '.0', '.1', '.2', '.4', '.2.1', '.3', '.4.1', '.5', '.5.1.5' ]

值是需要从最小到最大排序的层次结构的表示。我期待的结果是:

[ '.0', '.1', '.2.1', '.2, '.3', '.4', '.4.1', '.5', '.5.1.5' ]

我用于推入队列的方法在O(log n)运行,如下所示:

    queue.add = function(myval) {
        // console.log(myval);
        var i = this.size;
        this.array[this.size++] = myval;
        while ( i > 0) {
            var p = (i - 1) >> 1;
            var ap = this.array[p];
            if(!this.compare(myval, ap )) break;
            this.array[i] = ap;
            i = p;
        }
    };

我的比较功能很简单:

(a, b) => {
    return a[0] < b[0];
}

我正在考虑使用localeCompare但是因为我在Node中它似乎并不是出于某些原因而可靠。当我使用时:

(a, b) => {
    return a[0].localeCompare(b[0]) > 0;
}

我得到一个compareLocal未定义的错误,可能与其他内容有关。

因此,我的问题是,如何以我概述的方式有效地确定字符串排序?

3 个答案:

答案 0 :(得分:0)

虽然我的结果如下:

[".0", ".1", ".2", ".2.1", ".3", ".4", ".4.1", ".5", ".5.1.5"]

我希望这有帮助,我使用insert-sort来对这些值进行排序:

var arr = [ '.0', '.1', '.2', '.4', '.2.1', '.3', '.4.1', '.5', '.5.1.5' ];

// transform these values into '.21' or '.515' so that they can be sorted better
var transormedArray = arr.map(function(ele){
  return '.'+ele.replace(/[.]/g,'');
});

// insertion sort max-iterations n^2, min-iterations n(if already ordered)
for(var i=1; i< transormedArray.length; i++){
  for(var r=i;  r>=0 && transormedArray[r-1]>transormedArray[r]; r--){
      var tmp = transormedArray[r];
      transormedArray[r] = transormedArray[r-1];
      transormedArray[r-1] = tmp;
  }
}

// retransform them back into '.2.1' or '.5.1.5'
var result = transormedArray.map(function(ele){
  var str = ele.toString()[0];
  for(var i=1; i< ele.toString().length; i++){
    str += ele.toString()[i]+'.';
  }
  return str.slice(0,str.length-1);
});

console.log(result); // [".0", ".1", ".2", ".2.1", ".3", ".4", ".4.1", ".5", ".5.1.5"]

答案 1 :(得分:0)

您可以拆分字符串并比较各部分。

&#13;
&#13;
function customSort(data, order) {

    function isNumber(v) {
        return (+v).toString() === v;
    }

    var sort = {
            asc: function (a, b) {
                var i = 0,
                    l = Math.min(a.value.length, b.value.length);

                while (i < l && a.value[i] === b.value[i]) {
                    i++;
                }
                if (i === l) {
                    return a.value.length - b.value.length;
                }
                if (isNumber(a.value[i]) && isNumber(b.value[i])) {
                    return a.value[i] - b.value[i];
                }
                return a.value[i].localeCompare(b.value[i]);
            },
            desc: function (a, b) {
                return sort.asc(b, a);
            }
        },
        mapped = data.map(function (el, i) {
            return { index: i, value: el.split('.') };
        });

    mapped.sort(sort[order] || sort.asc);
    return mapped.map(function (el) {
        return data[el.index];
    });
}

var array = ['.0', '.1', '.2', '.4', '.2.1', '.3', '.4.1', '.5', '.5.1.5'];


console.log('sorted array asc', customSort(array));
console.log('sorted array desc ', customSort(array, 'desc'));
console.log('original array ', array);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;

答案 2 :(得分:0)

您可以创建一个自定义排序比较器方法,该方法将值拆分并比较它们的长度;及其整数值。

这是最简单,最直接的方法。

&#13;
&#13;
var compareVersions = (a, b) => {
    if (a === b) return 0;
    var aArr = a.split("."), bArr = b.split(".");
    for (var i = 0; i < Math.min(aArr.length, bArr.length); i++) {
        if (parseInt(aArr[i]) < parseInt(bArr[i])) return -1;
        if (parseInt(aArr[i]) > parseInt(bArr[i])) return 1;
    }
    if (aArr.length < bArr.length) return -1;
    if (aArr.length > bArr.length) return 1;
    return 0;
};
var compareVersionsDesc = (a, b) => compareVersions(b, a);

// Example
let versionArr = ['.0', '.1', '.2', '.4', '.2.1', '.3', '.4.1', '.5', '.5.1.5'];

console.log('Original Array: ', JSON.stringify(versionArr));
console.log('Sort Ascending:', JSON.stringify(versionArr.sort(compareVersions)));
console.log('Sort Descending:', JSON.stringify(versionArr.sort(compareVersionsDesc)));
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;