4

各要素の任意の最大値を持つ数値配列があります。[0, 0, 0]配列が からになるように要素をインクリメントするにはどうすればよいでしょう[x, y, z]か?

最大配列であるかどうかを説明するために、メイン配列をインクリメント[2, 1, 2]で開始すると、次の手順を実行してメイン配列を取得する必要があります。[0, 0, 0]

[0, 0, 0]
[1, 0, 0]
[2, 0, 0]
[0, 1, 0]
[1, 1, 0]
[2, 1, 0]
[0, 0, 1]
[1, 0, 1]
[2, 0, 1]
[0, 1, 1]
[1, 1, 1]
[2, 1, 1]
[0, 0, 2]
[1, 0, 2]
[2, 0, 2]
[0, 1, 2]
[1, 1, 2]
[2, 1, 2]

最大値の 1 に達するとすぐにインクリメントを停止する関数を作成しました。これが私のコードです。

var maxes = [2, 1, 2];
var myArray = [0, 0, 0];

function step() {
  for(var i = 0; i < myArray.length; i++) {
    if(myArray[i] == maxes[i]) {
       continue;
    } else {
       myArray[i] = myArray[i] + 1;
       return;
    }
  }
  return false;
}

for(j = 0; j < 100; j++) {
  result = step();
  if(!result) break;
  console.log(result);
}
4

5 に答える 5

1

公正な開示: これは私自身の質問です。私は自分の SO または電子メール ログインにアクセスできず、友人のために作成されたばかりの新しいアカウントでこの質問を投稿しました。私は質問や彼に答えを支持していません。また、友人に私の回答を承認済みとしてマークしてもらうこともありません。とにかく、私は問題に取り組み、最終的にこの作業コードにたどり着きました:

var maxes = [4,1,2,3];
var pattern = [0,0,0,0];

function step() {
  var t = false;
  for(var k = 0; k < pattern.length; k++) {
    t = t || (pattern[k] < maxes[k]);
  }
  if(!t) return false;
  for(k = 0; k < pattern.length; k++) {
    if(pattern[k] < maxes[k]) {
      pattern[k]++;
      return true;
    } else {
      pattern[k] = 0;
      continue;
    }
    return false;
  }
}

console.log(pattern);
var r = true;
while(r) {
  r = step();
  console.log(pattern);
}

JSBinはこちら

于 2012-12-22T08:52:52.623 に答える
0

解決すべきバグがいくつかあります。

var maxes   = [3, 1, 2, 1];
var myArray = [0, 0, 0, 0];

function step() {
  var changed = false;
  for(var i = 0; i < myArray.length; i++) {
    if(myArray[i] == maxes[i]) {
       continue;
    } else {
       myArray[i] = myArray[i] + 1;
       changed = true;
    }
  }
  return changed;
}

for(j = 0; j < 100; j++) {
  result = step();
  if(!result) break;
  console.log(myArray.join(", "));
}
于 2012-12-20T22:01:05.637 に答える
0

数日前にこの問題を再検討し、コードを少しリファクタリングしました。

最初に問題を正しく理解するために、それは混成基数システムでカウントすることに相当します。このシステムでは、位置/桁ごとに任意のベースがあります。たとえば、すべての最大値が 2 の場合、問題は基数 2 でカウントされますが、各位置の最大値は異なる数になる可能性があるため、ハイブリッド基数システムになります。

中央関数は実際には非常に単純です。

// increment in hyper system
function incr(maxes,num,digit) {
  num[digit] = num[digit] + 1;
  num[digit] = num[digit] % (maxes[digit]+1);
  if(num[digit] === 0) incr(maxes,num,digit+1);
}

そして、これが動作するjsbinです。

于 2013-07-27T10:00:51.583 に答える
-1

これは、より単純で効率的な解決策です。現在の位置を配列に格納する変数posを取得するだけです。現在の位置で最大値に達したら、現在の位置を 1 増やします。それ以外の場合は、現在の位置で値を増やします。そして、そのプロセスをposが最後の値達し、最後の値が最大になるまで繰り返し続けます。

var maxes = [3, 1, 2, 1];
var myArray = [0, 0, 0, 0];
var pos = 0;

while (pos < myArray.length - 1 || myArray[pos] < maxes[pos]) {
    if (myArray[pos] >= maxes[pos]) {
        myArray[pos] = 0; // to set it back to zero
        pos++;
        continue;
    } 
    myArray[pos]++;

    // Step code here
}

任意のサイズの配列で動作します。ここにjsfiddleがあります

于 2012-12-20T22:10:22.393 に答える