3

クイックで汚れた質問です。私は、一見単純なもののビット単位の操作のためのいくつかの基本的な知識が欠けているという感覚を得る。列挙型制限でビット単位の操作を使用して逆方向を取得します。

次のように私が解決しようとしている問題は、次のとおりです。


私は、グリッド内の位置からの移動の可能なすべてのベクトルを表す、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.

ホワイトボード私はあなたがここにビット演算をしたいと思ういけない過去の時間かそこら whiteboard of ultimate scratchheading

+1

一定の時間複雑性を持ったよう

基本的に1ベースのだろうこれを行うためのビット単位の演算可能な限り速く」_ビットの演算子は、 'let inverse = direction +(direction> 4?)で現在のアプローチよりも多くの演算を実行するでしょうか? -4:4) '? – guest271314

+0

それは良い質問です。私は実際にjavascriptがどのようにビット操作を行うかの詳細は知らないが、操作が現在の方法に必要な操作と同等かそれ以下であれば、より高速になると思うだろうか?これは、パスがメモリに格納される前に実際にパフォーマンスを向上させることができる唯一の場所であり、すべてのオペレーションがカウントされます。 – ShadowScripter

+0

@lleaffによってこの[回答](http://stackoverflow.com/a/34487506/)を参照してください – guest271314

答えて

1

用を見つめてきた、私は実際と思いますハードコードされた値を持つ配列は、単に値としてインデックスとして機能します。もちろん、それはメモリとして効率的ではありませんが、あなたは8の長さしか持たないので無視してもよいでしょう。

var inverseDirList = [5,6,7,8,1,2,3,4]; 
var invertedDirection = inverseDirList[direction - 1]; 

あなたが本当にあなたは、単にスタブ要素を追加することができ、方向値に任意の算術演算を実行していない気にした場合は、リストの先頭に、-1を言うので:

これを試してみてください「私は違うしようとしてきた_他の人はあなたがパフォーマンスをチェックし、比較するためにデベロッパーツールを使用することができます言及しているが、それによると、このstackoverflow question/answer JSハッシュ/配列検索が

+0

うーん、試してみるよ。これは最善のアプローチのようです。私はまだ知的に興味があり、頑固だからといってビット単位の演算を使ってこれを行う方法があるかどうかを知りたいのですが(それが可能であれば?)誰も実際に解決できない場合は受け入れます:) – ShadowScripter

+0

プロファイリングツールを間違って使用しているか、実際に差異が見られないか、または無視される可能性がありますか? 1,000万回以上の実行で、私は100〜200 msの差を得ました(合計時間は20秒です)。それでもなお良いです。 – ShadowScripter

関連する問題