2013-05-16 5 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

.

myhand[k] == vec[j][m] 일 때 k=0으로 만듭니다. 루프를 위해 j를 나눕니다.

그러나 k 루프는 0에서 다시 시작됩니다.

다시 myhand[k] == vec[j][m] 조건과 일치하면 계속됩니다. 이 외에도에서

, 당신은 루프를 작성하는 대신, std::find 알고리즘을 사용하는 것을 고려 등

1

std :: vector와 같은 비 연관 컨테이너에서 검색하는 것은 너무 비쌉니다.

std :: set는 문제가있는 도메인과 std :: set의 측면에서 합성 키 (카드의 4 튜플) 인 경우 찾을 수있는 손이 있다면 특별합니다. set은 특별한 수단이 없습니다.

"특정 구성 요소가 들어있는 키를 모두 찾으십시오."

std :: map도 문제의 한 부분만을 해결합니다.

부스트 :: bimap 고려,하지만 난 다른 접근 방식을 제안 할 수있다 :


문제의 데이터가 양자 그래프 (카드 손이 오른쪽, 왼쪽, 리터로 모델링 할 수 < -> R 에지 수단을 "핸드 버텍스"에서 볼 때 "카드 버텍스"와 "카드 포함"에서 "손에 있습니다".

따라서 자체 코딩 STL 기반 그래프보다 (STL 기반) 부스트 :: 그래프를 사용하는 것이 더 좋을 것입니다. 솔루션.


다른 실용적인 접근법은 SQLite를 사용하여 쉽게 만들 수있는 메모리 내장 데이터베이스에 의존합니다. pls 참석 http://www.sqlite.org/inmemorydb.html

관련 문제