2013-05-16 24 views
2

這對我想要做的事情來說太長了。 任何方式來使這個更快?如何在刪除矢量行時更快?

編輯對不起,我一直有一個高質量的郵政編碼問題,所以我只發佈最低限度。

我想要做的是一個奧馬哈撲克股權計算器。

A-它需要我們給他的4張卡片(myhand [4]),它會檢查所有可能的手的組合,看看是否有任何重複。

B-如果有任何重複的,它要刪除包含手 (所以當我們後來計算的股權,我們將不計算對一隻手是不可能有人有)

向量的行
int myhand[4] = { 3, 12, 22, 10 }; 
    vector<vector<int> > vec(4, vector<int>(270725)); 
    for (int m = 0; m < vec[0].size(); m++) { // A 
     for (int k = 0; k < 4; k++) { 
      for (int j = 0; j < 4; j++) 
       if (myhand[k] == vec[j][m]) { 
        for (int i = 0; i < 4; i++) { 
         vec[i].erase(vec[i].begin() + m); // B 
        } 
        k = 0; 
        j = 0; 
        break; 
       } 
     } 
    } 

有沒有辦法更有效的代碼?

感謝, Kaven

+7

這是什麼意思?瞭解代碼在高層應該達到什麼程度以查看最佳優化方式會非常有用。 –

+0

它看起來很奇怪... 4 for循環看起來像過度殺傷 –

+0

轉置矩陣可能會提高性能。 – stefan

回答

0

你最好構建組合,你想通過一個循環,看起來有點像這樣來處理:

#include <cassert> 
#include <algorithm> 
#include <vector> 
#include <iostream> 
#include <numeric> 

int main (int, char* []) 
{ 
    // Build a deck of cards 
    std::vector<int> deck(52); 
    std::iota(deck.begin(), deck.end(), 0); 

    // Remove 'myhand' 
    const int myhand[] = { 3, 12, 22, 10 }; 
    for (int i = 0; i < 4; ++i) { 
     deck[myhand[i]] = -1; 
    } 
    deck.resize(std::remove(deck.begin(), deck.end(), -1) - deck.begin()); 

    // Iterate over all possible remaining entries. 
    size_t num_processed = 0; 
    for (auto c1 = deck.begin(); c1 != deck.end(); ++c1) { 
     for (auto c2 = c1 + 1; c2 != deck.end(); ++c2) { 
      for (auto c3 = c2 + 1; c3 != deck.end(); ++c3) { 
       for (auto c4 = c3 + 1; c4 != deck.end(); ++c4) { 
        // Compute equity of (*c1, *c2, *c3, *c4) here. 

        ++num_processed; 
       } 
      } 
     } 
    } 
    // Verify that 48!/(44! * 4!) entries were processed. 
    assert (num_processed == (48*47*46*45)/(4*3*2*1)); 
    return 0; 
} 

順便說一句,我寫了一個德州撲克股權計算器。

+0

我正在做的事情非常像這樣,但是我不能像這樣產生隨機雙手,因爲如果我想在翻牌前的特定範圍(%)上進行計算,我必須尊重某些手牌排名。我會嘗試將其適用於我的代碼。非常感謝你。 – Daheh

0

試圖從我的理解來回答。

您在製作k=0myhand[k] == vec[j][m]。它打破了j循環。

但k for循環從零重新開始。

如果它再次匹配條件myhand[k] == vec[j][m],它會繼續。

除此之外,考慮使用std::find算法,而不是你寫循環等

1

在像std :: vector這樣的非關聯容器上搜索過於昂貴。

std :: set會很好,如果只是手被發現,但問題的關鍵是組合鍵(4元組卡)在問題領域和std :: set沒有特殊的手段處理諸如

「查找包含某個組件的所有密鑰」。

std :: map也只能解決問題的一部分。

的boost :: bimap的可以考慮,但我提出了不同的方法:


問題的數據可以由二分圖(卡離開,手上的權利,L建模< - > [R邊緣手段如果從「手頂點」看到的話,「卡頂點」和「包含卡片」中的「正在手中」

因此,我更喜歡使用基於STL的基於STL的解決方案。


另一種實用的方法是依靠內存數據庫,這可以很容易地使用SQLite創建;請參加 http://www.sqlite.org/inmemorydb.html