12

配列内の 3 つの最大値を見つけるには、この JavaScript コードのより最適化されたバージョンが必要です。最大数のインデックスを取得する必要があります。問題を解決するための他の簡単な方法はありますか?

var maxIndex = new Array();
var maxPoints = new Array();
var scoreByPattern = new Array(93, 17, 56, 91, 98, 33, 9, 38, 55, 78, 29, 81, 60);

function findLargest3() {
  maxPoints[0] = 0;
  maxPoints[1] = 0;
  maxPoints[2] = 0; 
  
  for (i = 0; i < scoreByPattern.length; i++) {
    if (scoreByPattern[i] > maxPoints[0]) {
      maxPoints[0] = scoreByPattern[i];
      maxIndex[0] = i;
    }
  }

  for (i = 0; i < scoreByPattern.length; i++) {
    if (scoreByPattern[i] > maxPoints[1] && scoreByPattern[i] < maxPoints[0]) {
      maxPoints[1] = scoreByPattern[i];
      maxIndex[1] = i;
    }
  }

  for (i = 0; i < scoreByPattern.length; i++) {
    if (scoreByPattern[i] > maxPoints[2] && scoreByPattern[i] < maxPoints[1]) {
      maxPoints[2] = scoreByPattern[i];
      maxIndex[2] = i;
    }
  }

  console.log(scoreByPattern + "/******/" + maxPoints[0] + "/" + maxPoints[1] + "/" + maxPoints[2]);
  //alert(maxIndex);
}

findLargest3();

4

14 に答える 14

13

修正版

回答をより一般的なものに変更しました。配列内の最大 n 個の要素のインデックスを検索します。

var scoreByPattern = [93,255,17,56,91,98,33,9,38,55,78,29,81,60];

function findIndicesOfMax(inp, count) {
    var outp = [];
    for (var i = 0; i < inp.length; i++) {
        outp.push(i); // add index to output array
        if (outp.length > count) {
            outp.sort(function(a, b) { return inp[b] - inp[a]; }); // descending sort the output array
            outp.pop(); // remove the last index (index of smallest element in output array)
        }
    }
    return outp;
}

// show original array
console.log(scoreByPattern);

// get indices of 3 greatest elements
var indices = findIndicesOfMax(scoreByPattern, 3);
console.log(indices);

// show 3 greatest scores
for (var i = 0; i < indices.length; i++)
    console.log(scoreByPattern[indices[i]]);

ここにjsFiddleがあります

于 2012-08-03T08:40:07.683 に答える
9

配列を降順に並べ替えることができます。次に、上位 3 つの値のインデックスが配列の最初の 3 つの項目になります。個別にアクセスすることslice()も、一度に取得するために使用することもできます。以下の例は、両方の方法を示しています。

var maxPoints = new Array();
var scoreByPattern = new Array(93, 17, 56, 91, 98, 33, 9, 38, 55, 78, 29, 81, 60);

findLargest3();

function findLargest3() {
  scoreByPattern.sort((a, b) => a < b ? 1 : a > b ? -1 : 0);
  
  console.log(scoreByPattern + "/******/" + scoreByPattern[0] + "/" + scoreByPattern[1] + "/" + scoreByPattern[2]);  
  console.log(scoreByPattern.slice(0, 3));
}

于 2012-08-03T08:38:53.477 に答える
7

巨大な配列をソートせずに:O(n)元の配列をソートするよりも優れた実行。初期配列内の最大値とそのインデックスの配列を返します。よりスマートなコードを使用すると、小さな配列の並べ替えをなくすことができ、最悪の場合のパフォーマンスが向上します。

var ar = [93, 17, 56, 91, 98, 33, 9, 38, 55, 78, 29, 81, 60];
console.log(`input is: ${ar}`);

function getMax(ar){
    if (ar.length <= 3) return ar;
    let max = [{value:ar[0],index:0},
               {value:ar[1],index:1},
               {value:ar[2],index:2}];
    max.sort((a,b)=>a.value-b.value);
        
    for (let i = 3;i<ar.length;i++){
        if (ar[i] > max[0].value){
           max[0] = {value:ar[i],index:i};
           max.sort((a,b)=>a.value-b.value);
        }
    }
    return max;
}

result = getMax(ar);

console.log('the three largest values are:');
console.log(result);

于 2012-08-03T08:52:16.477 に答える
4

デフォルトの JavaScript ソート コールバックは、辞書順でソートされるため、うまく機能しません。10 は 5 の前になります (1 のため)

私への信用はありませんが:

my_array.sort(function(a,b) {
    return a-b;
});
于 2012-08-03T08:40:27.920 に答える
3

最良の方法は、 sortsliceを組み合わせて使用​​することです。

このシンプルなワンライナーで問題が解決します。

[1, -5, 2, 8, 17, 0, -2].sort(function(a, b){return b - a}).slice(0, 3)

したがって、配列があり、N 個の最大値を見つけたい場合:

arr.sort(function(a, b){return b - a}).slice(0, n)

N 個の最小値の場合:

arr.sort(function(a, b){return a - b}).slice(0, n)
于 2014-02-10T23:31:11.363 に答える
2

かなり正規分布であると仮定すると、これはかなり最適なはずです。

var max_three, numbers = new Array(93,17,56,91,98,33,9,38,55,78,29,81,60);

max_three = (function (numbers) {
    var i, one, two, three;
    one = -9999;
    two = -9999;
    three = -9999;

    for (i = 0; i < numbers.length; i += 1) {
        num = numbers[i];
        if (num > three) {
            if (num >= two) {
                three = two;
                if (num >= one) {
                    two = one;
                    one = num;
                }
                else {
                    two = num;
                }
            }
            else {
                three = num;
            }
        }
    }

    return [one, two, three]

}(numbers))



document.write(max_three)​​​​​​​

98,93,91

于 2012-08-03T08:48:35.277 に答える
0

http://jsfiddle.net/GGkSt/

var maxPoints = [];
var scoreByPattern = [93,17,56,91,98,33,9,38,55,78,29,81,60];

function cloneArray(array) {
    return array.map(function(i){ return i; });
}    
function max3(array) {
    return cloneArray(array).sort(function(a,b) { return b-a; }).slice(0,3);
}
function min3(array) {
     return cloneArray(array).sort(function(a,b) { return a-b; }).slice(0,3);
}

var array=scoreByPattern;
alert("Max:"+ max3(array)[0] +' '+max3(array)[1] +' '+max3(array)[2]);
alert("Min:"+ min3(array)[0] +' '+min3(array)[1] +' '+min3(array)[2]);
于 2012-08-03T08:54:31.857 に答える
0

それを並べ替えて、最初 (または昇順で並べ替えられている場合は最後) の 3 つの要素を取得してみませんか。

var maxPoints = new Array();
var scoreByPattern = new Array(93,17,56,91,98,33,9,38,55,78,29,81,60);
scoreByPattern.sort();
maxPoints[0] = scoreByPattern[scoreByPattern.length - 1];
maxPoints[1] = scoreByPattern[scoreByPattern.length - 2];
maxPoints[2] = scoreByPattern[scoreByPattern.length - 3];

編集
最大の配列のインデックスが必要な場合は、コピーを作成して並べ替え、元の配列のインデックスを見つけることができます。

var scoreByPattern = new Array(93,17,56,91,98,33,9,38,55,78,29,81,60);

// Make a copy of the original array.
var maxPoints = scoreByPattern.slice();

// Sort in descending order.
maxPoints.sort(function(a, b) {
    if (a < b) { return 1; }
    else if (a == b) { return 0; }
    else { return -1; }

});

// Find the indices of the three largest elements in the original array.
var maxPointsIndices = new Array();
maxPointsIndices[0] = scoreByPattern.indexOf(maxPoints[0]);
maxPointsIndices[1] = scoreByPattern.indexOf(maxPoints[1]);
maxPointsIndices[2] = scoreByPattern.indexOf(maxPoints[2]);

ソートせずにインデックスを見つける別の方法は次のとおりです。

var scoreByPattern = new Array(93,17,56,91,98,33,9,38,55,78,29,81,60);
var maxIndices = new Array(Number.MIN_VALUE, Number.MIN_VALUE, Number.MIN_VALUE);

for (var i = 0; i < scoreByPattern.length; i++) {
  if (maxIndices[0] < scoreByPattern[i]) {
    maxIndices[2] = maxIndices[1];
    maxIndices[1] = maxIndices[0];
    maxIndices[0] = scoreByPattern[i];
  }
  else if (maxIndices[1] < scoreByPattern[i]) {
    maxIndices[2] = maxIndices[1];
    maxIndices[1] = scoreByPattern[i];
  }
  else if (maxIndices[2] < scoreByPattern[i]) maxIndices[2] = scoreByPattern[i];
}
于 2012-08-03T08:37:04.800 に答える
0

ソートなしのソリューションは次のとおりです。

let getLargest = (a,n)=>{
    let max,p,b=[],n1;
    for(let i=0;i<n;i++){
        max=a[0]
        p=false
        n1=0
        for(let j in a){
            if(max<a[j]){
                max=a[j]
                p=true
                n1=j
            }
        }
        if(!!p){
            b.push(max)
            a.splice(n1,1);
        }
    }
    console.log(a)
    return b;
}

console.log(getLargest([5.03, 7.09, 6.56,  9.09, 11.11], 3))
console.log(getLargest([5.03, 7.09, 6.56,  9.09, 11.11], 4))
console.log(getLargest([5.03, 7.09, 6.56,  9.09, 11.11], 1))
console.log(getLargest([5.03, 7.09, 6.56,  9.09, 11.11], 2))

n ループの場合、最大値を探して元の配列から削除し、新しい配列にプッシュします。n 個の大きな要素を取得できます。

于 2021-12-03T03:47:05.123 に答える