2014-08-29 2 views
1
#include <iostream> 
#include <stdlib.h> 
#include <time.h> 
using namespace std; 

void randnum() 
{ 
    int random; 
    srand((unsigned int)time(0)); 
    for(int i=1;i<=5;i++) 
    { 
     random=(rand()%39)+1; 
     cout<<random<<endl; 
    } 
} 

int main() 
{ 
    cout<<"Five random number is here"<<endl; 
    randnum(); 
    system ("PAUSE"); 
    return 0; 
} 

나는 무작위로 이것을 연습하여 C++를 연습합니다. 난 항상 무작위 발전기의 범위를 설정에 혼란스러워 (내 방법은 정확합니까? 1-39). 또한 숫자가 서로 겹치지 않게하려면 어떻게해야합니까? 즉, 1-39에서 5 개의 다른 숫자를 출력하는 경우 4,5,2,4,12 대신 4,5,2,7,12와 같은 5 개의 숫자를 사용할 수 있습니다 (여기서 4는 두 번 사용됩니다)숫자가 겹치지 않게 1에서 39까지 임의의 숫자를 생성하려면 어떻게해야합니까?

+2

만약'C++ '를 사용한다면 표준 라이브러리를 사용하십시오. http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution을 참조하십시오. – imreal

+2

1에서 39까지 5 개의 숫자를 선택하려면 벡터에 해당 숫자를 모두 추가하고 셔플 링 한 다음 첫 번째 5 번. –

+1

그리고 그렇게하는 동안'std :: iota'와'std :: shuffle'을 염두에 두라. – chris

답변

3

예, 1에서 39 사이의 임의의 숫자를 가져 오는 방법이 정확합니다.

  1. 이미 게재 된 숫자의 집합을 유지하고 그들이 두 번째로 선택됩니다 때 건너 뛰거나
  2. 모든 목록을 작성 :

    두 알고리즘이 마음에 와서, 겹치지 않는 번호를 확인하려면 후보 번호를 무작위로 배열 한 다음 순서대로 제공하십시오.

1

올바른 방법입니다. 숫자가 서로 겹치지 않게하려면, 가장 좋은 해결책은 이미 생성 된 숫자의 벡터를 만들고, 새로운 난수를 생성 할 때마다 이미 벡터에 있는지 확인하는 것입니다. 그렇다면 재생성하십시오. 그렇지 않으면 벡터에 추가하고 계속 진행합니다.

+4

더 많은 숫자를 생성 할 때 점차적으로 속도가 느려질 것입니다. "불량"결과의 수가 올라감에 따라 재 시도해야하기 때문입니다. 특정한 경우에는 괜찮을 지 모르지만 큰 숫자로는 일반화되지 않습니다. –

+0

@CraigMcQueen : 이것이 문제라면, 이미 사용 된 값을'bitset','set' 또는'unordered_set'에서 추적 할 수 있지만 일반적인 접근법은 유효합니다. +1 –

+0

@TonyD 이렇게하면 생성 된 숫자가 이미 사용되었는지 확인하는 속도가 빨라집니다. 그러나 "이미 사용 된"값의 수가 올라감에 따라 점점 더 무작위의 세대를 다시 시도해야하는 문제는 여전히 남아 있습니다. –

1

랜덤 = (rand() % 39) +1;

중복 될 수 있습니다.


범위 [begin,end]의 요소 수 (브래킷 수단

항상 난수 발생기의 설정 범위에서의 혼란 (1-39에서 정확한 내 방법?이다)

) "포함"입니다 :

count = end - begin + 1 

당신은 당신이 수행 한 공 기반 count 요소를해야하는 경우 :

내가 겹쳐 번호를 방지 할 수있는 방법 또한

rand() % count + begin 

: 시작 요소가 하지 0이 될 수 있기 때문에

rand() % count 

, 당신은 실제로 범위의 값을 얻기 위해 다음을 수행 서로?

이 경우 더 쉬운 해결책 중 하나는 벡터를 사용하는 것입니다. 그것은 다른 답변 (@ Resired Ninja가 제안한 것과 같은)만큼 효율적이지 않지만 이해하기 쉽습니다. 아래에 표시된 것과 같습니다.

다음 코드는 셔플 결과를 덤프합니다 (사용 된 코드는 seed에 따라 반복 실행되기 때문에 무작위가 아닙니다). 처음 5 가지 요소에 맞추기가 어렵지 않아야합니다 (모든 답을 줄 수는 없습니다).당신이 seed (기본값은 0이다), 당신은 얻을 것이다 다른 순서를 지정하는 경우

ShuffledRange range (1, 39); 
... 

$ ./tt.exe 
29 33 8 37 9 32 38 24 16 14 36 7 10 31 34 39 27 11 6 4 35 1 19 20 18 15 5 12 22 
21 3 30 17 25 2 28 23 26 13 

는 :

ShuffledRange range (1, 39, 2); 
... 

$ ./tt.exe 
12 20 28 6 7 15 32 17 35 11 18 31 27 4 23 36 25 24 22 1 33 2 37 39 21 9 38 13 5 3 
14 10 8 34 16 19 29 26 30 

아래 코드는 C++ (11) 때문에 random_shuffle의 필요합니다.

$ g++ -Wall -Wextra -std=c++11 tt.cpp -o tt.exe 

및 Mac OS X :

$ g++ -Wall -Wextra -std=c++11 -stdlib=libc++ tt.cpp -o tt.exe 

class ShuffledRange 
{ 
public: 

    explicit ShuffledRange(unsigned int low, unsigned int high, int seed=0) 
     : m_numbers(move(create_numbers(low,high,seed))), m_it(m_numbers.begin()) { } 

    unsigned int GetCount() const { 
     return static_cast<unsigned int>(m_numbers.size()); 
    } 

    bool HasNext() const { 
     return m_it != m_numbers.end(); 
    } 

    unsigned int GetNext() 
    { 
     if(!HasNext()) 
      throw std::runtime_error("No numbers left"); 

     unsigned int temp = *m_it++; 
     return temp; 
    } 

protected:     

    vector<unsigned int> create_numbers(unsigned int low, unsigned int high, int seed) 
    { 
     if(high < low) 
      throw std::runtime_error("Bad range of elements"); 

     vector<unsigned int> temp; 
     temp.reserve(high - low + 1); 

     for(unsigned int i = low; i <= high; i++) 
      temp.push_back(i); 

     srand(seed); 
     random_shuffle(temp.begin(), temp.end()); 

     return temp; 
    } 

private: 

    vector<unsigned int> m_numbers; 
    vector<unsigned int>::iterator m_it; 
}; 

int main(int argc, char* argv[]) 
{ 
    ShuffledRange range(1, 39); 

    while(range.HasNext()) 
     cout << range.GetNext() << " "; 

    cout << endl; 

    return 0; 
} 
비주얼 스튜디오 2012 나 2010 년

GCC 필요한 비주얼 스튜디오에 대한 확실하지 않다 C++ (11)와 잘해야한다


힌트 ....

당신이 main의 닫는 중괄호 (즉, }가), 당신은 system ("PAUSE"); 필요하지 않습니다에 중단 점 ( F9)를 배치하면 17,451,515,
int main() 
{ 
    cout<<"Five random number is here"<<endl; 
    randnum(); 
    system ("PAUSE"); 
    return 0; 
} 

. Visual Studio가 중단되어 사용자를 기다립니다. 값을 검사했으면 F5을 눌러 프로그램을 마칩니다.

1

숫자가 1-39 인 벡터를 만들어 셔플 한 다음 처음 5 개를 선택합니다. 그런 다음 5 개의 반복되지 않는 임의의 숫자가 있습니다.

random_shuffle() 함수는 C++ 라이브러리에서 구현됩니다. 여기에서 확인하십시오 : http://www.cplusplus.com/reference/algorithm/random_shuffle/