簡體   English   中英

在Javascript(Node.js)中分析此數組的最有效方法?

[英]Most efficient way to analyze this array in Javascript (Node.js)?

首先,我想指出這是服務器端的Node.js代碼,而不是普通的客戶端Javascript。 我不想使用jQuery,但使用任何本機Node.js方法(如果你知道任何可能有用的方法)都沒問題。

這是紙牌游戲中的機器人玩家的代碼。 機器人的手牌結構如下:

[ '9H', '10S', 'KD', '9D', '7D', 'QC', 'JC', '7C' ]

所以8張牌中的每一張都是一個value+suit字符串。 這是無法更改的,因為整個應用程序都適用於此結構。

現在,機器人必須分析這只手以搜索某些卡片組合。 例如,它應該找到任何“第三王”(國王至少有2張相同套裝的小牌),“第二王”(女王至少有1張相同套裝的小牌)或“第三王后”。

在上面的例子中,它應該提出:第三王鑽石和第三王牌俱樂部。

我正在尋找實現搜索算法來找到這些組合,但我擔心它會非常低效。 我的第一個想法是遍歷數組以找到所有的國王,王后和10並將這些數據保存在某處,然后再次迭代它以計算我們擁有的同一套牌的其他牌數。 例如,對於國王:

var kingsuits = [];
for(var i=0;i<8;i++){
    if(hand[i].substr(0,1) == "K")
        kingsuits.push(hand[i].substr(-1));
}
//now kingsuits has the suits of all kings, and we can go through our hand again and check how many cards we have in each of these suits...

我的問題是,有沒有更有效的方法來實現這一目標? 問題是,還有很多其他組合也應該被尋找,而不僅僅是我在上面舉例說明的那些組合。

另外 - 也許更重要的是 - 如果我們找到“第三王”,我們根本不需要尋找“第三王后”或“第二王牌”。 這些組合有一個明確的層次結構,所以如果我們找到第一個組合,我們根本不需要關心其他組合。

使用二維hashmap或數組或某種其他類型的直接訪問數據結構,在該數據結構中存儲特定類型的(boolean)或多少(int)卡。 例如:

[ '9H', '10S', 'KD', '9D', '7D', 'QC', 'JC', '7C' ]
=>
  | A  K  Q  J  10 9  8  7  6  5  4  3  2
--+--------------------------------------
C | 0  0  1  1  0  0  0  1  0  0  0  0  0
D | 0  1  0  0  0  1  0  0  0  0  0  0  0
H | 0  0  0  0  0  1  0  0  0  0  0  0  0
S | 0  0  0  0  1  0  0  0  0  0  0  0  0

這應該允許在該結構中進行非常快速和簡單的搜索 - 通過循環,您可以快速識別出有多個9,並且俱樂部女王旁邊有2張俱樂部卡。

是否為黑桃選擇一個對象或一個數組並且哪些(套裝或值)是第一維或第二維並不重要。 對於值,您將需要使用數組來獲取定義的順序,即使映射(例如A-> 0,K-> 1,... 2-> 12)是非常規的。

一個快速的解決方案是首先快速將手分類為套裝/數字順序,即:

[ '9H', '10S', '7D', '9D', 'KD', '7C', 'JC', 'QC' ]

然后在列表中進行單次傳遞,跟蹤到目前為止發現的單個套裝中最長的卡片順序,例如:

var lastCard
var currentSequence
var bestSequence

for card in cards:
  if suitOf(card) = suitOf(lastCard) and numberOf(card) = numberOf(lastCard) + 1:
    append to currentSequence
  else:
    if currentSequence better than bestSequence:
      bestSequence = currentSequence
    clear currentSequence

當您找到“最佳”序列時,可以輕松中止搜索。

由於關於您正在搜索的內容存在許多未知數,因此可能只需對卡進行排序即可,但您可以考慮將卡排列在對象(哈希表)中以快速查找條件。

function value(s) {
    return s.substr(0, s.length - 1)
}

function suit(s) {
    return s.substr(-1)
}


function search(arr) {
    var suits = {
        S: {},
        C: {},
        D: {},
        H: {}
    }

    var count = {
        S: 0,
        C: 0,
        D: 0,
        H: 0
    }

    for (var i = 0; i < arr.length; i++) {
        var card = arr[i]
        var s = suit(card)
        var v = value(card)

        suits[s][v] = true
        count[s]++
    }

    // hunt in the structure here
}

這將允許您獲取第三個皇后,例如:

var thirdQueens = ["S", "C", "D", "H"].map(function (s) {
    var hash = suits[s]

    if (hash.Q && count[s] - (hash.K ? 1 : 0) >= 3) {
        return "Q" + s
    }
}).filter(function identity(x) { return x })

...這里是你的hashmap的構造方式......我想其他任何東西都已在我面前解釋過了。

var input = [ '9H', '10S', 'KD', '9D', '7D', 'QC', 'JC', '7C' ]

var M = [ [], [], [], [] ]

var values = {
  2:  0,
  3:  1,
  4:  2,
  5:  3,
  6:  4,
  7:  5,
  8:  6,
  9:  7,
 10:  8,
  J:  9,
  Q: 10,
  K: 11,
  A: 12,
}

var suits = {
  C: 0,
  D: 1,
  H: 2,
  S: 3,
}

input.forEach(function(x) {
  M[suits[x.slice(-1)]][values[x.slice(0, -1)]] = 1
})

要回答問題的“更重要”部分,您可以按優先順序創建一系列規則,為每個規則創建一個函數,然后迭代它。 這是一個非常簡單的例子:

var hand = [ '9H', '10S', 'KD', '9D', '7D', 'QC', 'JC', '7C' ];

var rules = [
    function(hand) {
        if (hand.indexOf('9H') !== -1) {
            return {
                rule: "Has a 9H",
                cards: [ "9H" ]
            };
        }
    },

    function(hand) {

        if (hand.indexOf('7D') !== -1) {
            return {
                rule: "Has a 7D",
                cards: [ "7D" ]
            };
        }
    }
];

var match = false;

for (var i = 0, len = rules.length; i < len && !match; ++i) {
    match = rules[i](hand);
}

console.log(match);

編寫完成后,您可以查看規則並檢查邏輯的重復,然后開始重寫規則:

var rules = [
    matchCardFn("9H"),
    matchCardFn("7D")
];

function matchCardFn(matchCard) {
    return function(hand) {
        if (hand.indexOf(matchCard) !== -1) {
            return {
                rule: "Has a " + matchCard,
                cards: [ matchCard ]
            };
        }
    };
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM