クイックで汚れた質問です。私は、一見単純なもののビット単位の操作のためのいくつかの基本的な知識が欠けているという感覚を得る。列挙型制限でビット単位の操作を使用して逆方向を取得します。
次のように私が解決しようとしている問題は、次のとおりです。
私は、グリッド内の位置からの移動の可能なすべてのベクトルを表す、1と8の間の整数の列挙を持っています。
(私はあなたのいくつかは、この問題を認識することができる想像)
{
TOP: 1,
TOP_RIGHT: 2,
RIGHT: 3,
BOTTOM_RIGHT: 4,
BOTTOM: 5,
BOTTOM_LEFT: 6,
LEFT: 7,
TOP_LEFT: 8,
}
グリッド上の位置のパスを考えると、2点間、これらはそのパスに沿って動きを表現するために使用することができます。
[
{x: 22, y: 30},
{x: 22, y: 29},
{x: 22, y: 28},
{x: 23, y: 27},
{x: 24, y: 26},
{x: 25, y: 25},
{x: 26, y: 25},
{x: 27, y: 24},
{x: 26, y: 23},
{x: 27, y: 22},
{x: 26, y: 22}
]
は、最終的には、文字列私は最善の方向を反転するにはどうすればよい
"1122232827"
として表現されますか?
私はできるだけ早くこれを行うためにビットごとの異なる操作を試みてきましたが、私はそれを理解できません(これは大きなボトルネックです)。これまでは、方向が限界の半分を超えているかどうかを確認し、その半分を削除または追加する場合は、省略形を使用していました。しかし、再び、私はこれがより効率的にいくつかのbitwise jiggeryで行うことができると思っています。以下のコードで何でも自由にしてください。
注:ルックアップマップ、方向ベクトルと方向を取得する方法定数であり、はを変更することはできません。それらは実際には特定のAPIのフードの下で何が起こるかの解釈であり、おそらくはるかに優れた実装です。
// Enum of vectors
let vectors = {
\t TOP: 1,
\t TOP_RIGHT: 2,
\t RIGHT: 3,
\t BOTTOM_RIGHT: 4,
\t BOTTOM: 5,
\t BOTTOM_LEFT: 6,
\t LEFT: 7,
\t TOP_LEFT: 8,
};
_.extend(window, vectors); // Add them to global
// Lookup table for vectors
let dirMap = {
\t 1: { 1: TOP_RIGHT, 0: RIGHT, "-1": BOTTOM_RIGHT },
\t 0: { 1: TOP, "-1": BOTTOM, },
\t "-1": { 1: TOP_LEFT, 0: LEFT, "-1": BOTTOM_LEFT }
};
// Get the direction key
function getDirection(a, b){
\t return dirMap[b.x - a.x][a.y - b.y];
}
// Example path
let path = [
\t {x: 22, y: 30},
\t {x: 22, y: 29},
\t {x: 22, y: 28},
\t {x: 23, y: 27},
\t {x: 24, y: 26},
\t {x: 25, y: 25},
\t {x: 26, y: 25},
\t {x: 27, y: 24},
\t {x: 26, y: 23},
\t {x: 27, y: 22},
\t {x: 26, y: 22}
];
let strPath = "", strInverted = "";
for(let i = 1, len = path.length; i < len; i++){
\t let prev = path[i - 1];
\t let direction = getDirection(prev, path[i]);
\t let inverse = direction + (direction > 4 ? -4 : 4); // Can I turn this into a bitwise operation?
\t strPath += direction;
\t strInverted = inverse + strInverted;
}
console.log("Forward: ", strPath);
console.log("Reverse: ", strInverted);
document.getElementById("forward").innerHTML = strPath;
document.getElementById("reverse").innerHTML = strInverted;
// Just for debugging purposes
function getDirString(dirString){
\t let arrDir = [];
_.each(dirString, function(c){
\t let val = parseInt(c), dir = "";
_.find(vectors, function(o, i){ if(o === val){ dir = i; return true; }});
arrDir.push(dir);
\t });
return arrDir.join(", ");
}
document.getElementById("full_forward").innerHTML = getDirString(strPath);
document.getElementById("full_reverse").innerHTML = getDirString(strInverted);
body{ font-family: Arial, Helvetica, sans-serif; }
#forward:before, #reverse:before, #full_forward:before, #full_reverse:before{
display: inline-block;
margin-right: 1em;
width: 4em;
}
#full_forward, #full_reverse{font-size: 0.7em; white-space: nowrap;}
#forward:before{ content: "Forward:"; }
#reverse:before{ content: "Reverse:"; }
#full_forward:before{ content: "Forward:"; }
#full_reverse:before{ content: "Reverse:"; }
<script src="https://cdn.jsdelivr.net/lodash/2.1.0/lodash.compat.js"></script>
<div id="forward"></div>
<div id="reverse"></div>
<br>
<div id="full_forward"></div>
<div id="full_reverse"></div>
Here's a jsfiddle to play with.
ホワイトボード私はあなたがここにビット演算をしたいと思ういけない過去の時間かそこら
一定の時間複雑性を持ったよう
基本的に1ベースのだろうこれを行うためのビット単位の演算可能な限り速く」_ビットの演算子は、 'let inverse = direction +(direction> 4?)で現在のアプローチよりも多くの演算を実行するでしょうか? -4:4) '? – guest271314
それは良い質問です。私は実際にjavascriptがどのようにビット操作を行うかの詳細は知らないが、操作が現在の方法に必要な操作と同等かそれ以下であれば、より高速になると思うだろうか?これは、パスがメモリに格納される前に実際にパフォーマンスを向上させることができる唯一の場所であり、すべてのオペレーションがカウントされます。 – ShadowScripter
@lleaffによってこの[回答](http://stackoverflow.com/a/34487506/)を参照してください – guest271314