关于字典排序的数组元素的等级

时间:2013-05-15 21:33:41

标签: javascript algorithm

我有一个长度为A的数组n,其中包含长度为3的字符串。我想构建一个数组B,其中A中的每个字符串都被其等级替换在A中关于词典排序。 (请注意A可能有重复项,因此B也可能有重复项。)

假设JavaScript A.sort()及时A执行基数排序O(n),我如何在B时间O(n)内构建A }?

示例:如果A

['abb', 'ada', 'bba', 'bba', 'dab', 'bad']

然后B

[1, 2, 4, 4, 5, 3]

(注意:您可以假设阵列分配需要一段时间。)

5 个答案:

答案 0 :(得分:2)

这是我能想到的最快的事情......

function cheese(a){
    var b = [];
    var c = {};//hash references to make lookups really fast
    var d = [];//desired output
    for(var i = 0; i < a.length; i++)
    {
        if(!c[a[i]])
            b.push(a[i]);
        c[a[i]] = true;
    }
    b.sort();
    for(i = 0; i < b.length; i++)
    {
        c[b[i]] = i;
    }
    for(i = 0; i < a.length; i++)
        d.push(c[a[i]] + 1);
    return d;
}

答案 1 :(得分:0)

我会尝试,但我对此感到不自信:

  • 跨浏览器实现排序算法一致性
  • 我的解决方案可以简化,而且没有经过广泛测试。

无论如何,它似乎给出了理想的结果,所以让我们走吧:

Array.prototype.getLexicoGraphic = function() {
    var result = [], 
        sorted = this.slice(0).sort();

    for(var i = 0; i < sorted.length; i ++) {
        result[i] = sorted.indexOf(this[i]) - (i - sorted.indexOf(sorted[i])) + 1;    
    }

    return result;
}

答案 2 :(得分:0)

构造辅助数组,该数组将包含该值及其原始索引 - O(n)

[[0, 'abb'], [1, 'ada'], [2, 'bba'], [3, 'bba'], [4, 'dab'], [5, 'bad']] // Stored as 'foo' in the following examples

使用comparator function对新创建的数组进行排序 - 根据您的假设O(n)(但我对此表示怀疑)。

foo.sort(function (a, b) { return a[1].localeCompare(b[1]); });

迭代排序后的数组并在路上创建排名数组 - O(n)

var last = null, rank = 0, result = [], i;
for (i = 0; i < foo.length; i++) {
    result[foo[i][0]] = (last === null || last.localeCompare(foo[i][1]) != 0) ? ++rank : rank;
    last = foo[i][1];
}

享受您的result


更新另一种方法是通过带索引的关联数组:

{ 'abb': [0], 'ada': [1], 'bba': [2, 3], 'dab': [4], 'bad': [5] }

然后你可以创建一组键(因此是唯一值),对它进行排序并根据它构建你的排名。

答案 3 :(得分:0)

var A = ['abb', 'ada', 'bba', 'bba', 'dab', 'bad'];
var B = [];

// Assuming slice(0) is O(n) 
var Ap = A.slice(0);
var H = [];

var N = A.length;
var i, index;

// O(n)
A.sort();

// O(n)
for (index = 1, i = 0; i < N; i++) {
    // Assuming that H[A[i]] is O(1)
    if (!H[A[i]]) { 
        H[A[i]] = index;
        index++;
    }
}

// O(n)
for (i = 0; i < N; i++) {
    B[i] = H[Ap[i]];
}
console.log(B);

// 4 * O(n) === O(n)

答案 4 :(得分:0)

您可以在O(n)时间

中创建一个序数数组
var a = ...;

var ranks = [];
for (var i = 0; i < a.length; ++i) { ranks[i] = i; }

然后,您可以定义一个比较器,通过比较索引字符串

来比较整数
function cmp(i, j) {
  return a[i] < a[j] ? -1 : a[i] = a[j] ? 0 : 1;
}

由于字符串是恒定长度,因此每次比较都需要恒定的时间。

然后在ranks上执行自定义排序,而不是使用您规定的cmp需要线性时间。这将产生b

如果您需要a的排序版本,则可以在线性时间内从aranks重新构建它。

var aSorted = [];
for (var i = 0; i < a.length; ++i) {
  aSorted[i] = a[ranks[i]];
}