C ++에서 루프를 다시 시작하는 방법 (임의 실행을 통해 고유 한 시퀀스 찾기)

StackOverflow https://stackoverflow.com/questions/614012

  •  03-07-2019
  •  | 
  •  

문제

다음 코드는 k 런을 통해 임의의 문자열을 생성하려고합니다. 그러나 우리는 새로 생성 된 문자열이 참조 문자열과 완전히 다르기를 원합니다.

이를 위해 나는 "계속"을 사용하여 임의의 문자열 생성 프로세스를 다시 시작하려고 노력했습니다. 그러나 작동하지 않는 것 같습니다. 아래 내 접근 방식에 무슨 문제가 있습니까?

#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <time.h>
using namespace std;


// In this code we want to print new string that is entirely different with  
// with those in initVector 


template <typename T> void  prn_vec(std::vector < T >&arg, string sep="")
{   // simple function for printing vector
    for (int n = 0; n < arg.size(); n++) {
        cout << arg[n] << sep; 
    }
}


int main  ( int arg_count, char *arg_vec[] ) {

    // This is reference string
    vector <string> initVec;
    initVec.push_back("A");
    initVec.push_back("A");
    initVec.push_back("A");
    initVec.push_back("A");

    vector <string> DNA;
      DNA.push_back("A");
      DNA.push_back("C");
      DNA.push_back("G");
      DNA.push_back("T");

    for (unsigned i =0; i< 10000; i++) {

       vector <string> newString;
       for(unsigned j=0; j<initVec.size(); j++) {

         int dnaNo = rand() % 4;
         string newBase = DNA[dnaNo];
         string oldBase = initVec[j];

         int sameCount = 0;
         if (newBase == oldBase) {
            sameCount++;
         }

         if (sameCount == initVec.size()) {
              continue;
         }

         newString.push_back(newBase);

       } 
       cout << "Run " << i << " : ";
       prn_vec<string>(newString);
       cout << endl;

    }

    return 0;
}
도움이 되었습니까?

해결책

요구 사항의 큰 부분을 놓치지 않는 한 코드는 언뜻보기에 잘 보입니다. 읽다 이것 사용하기 전에 rand(). 물론 continue 부분. 당신이하려고하는 것은 이것이 initVector 아니면 그렇지 않습니까? 간단한 비교는 콘솔에 넣거나 인쇄하기 전에해야합니다.

int sameCount = 0;
if (newBase == oldBase) {
 sameCount++;
}
// sameCount can be 1 at most, 0 otherwise
// this check never return true
if (sameCount == initVec.size()) {
continue;
}

그만큼 sameCount 변수는 새 항목을 만들 때마다 초기화됩니다. newString 폐쇄시 범위를 벗어납니다 }for 고리. 따라서 중복 생성에 대한 적절한 점검으로 기능하는 것은 증가하지 않습니다. 이상적으로는 a를 사용해야합니다 std::set 그리고 계속 삽입하십시오. 복제물은 허용되지 않으며 많은 문제로부터 저장됩니다.

사용에 대한 자세한 내용 rand() srand() 그리고 무작위 숫자 생성 :

comp.lang.c faq에서 :

...] 많은 임의 번호 생성기의 저차 비트는 고통스럽게 비 랜덤입니다.

랜덤 번호를 범위에 유지하려면

[0, 1, ... N - 1]

단순에 비해 더 나은 방법입니다 rand() % N (링크에서 조언 한 바와 같이) 다음을 사용해야합니다.

(int)((double)rand() / ((double)RAND_MAX + 1) * N)

이제 프로그램을 실행하려면 10000 홀수 랜덤 DNA 가닥을 얻을 때마다 매번 얻을 수 있습니다. 이것은 다음과 같습니다.

그것은 대부분의 의사 랜덤 번호 생성기 (및 C 라이브러리 랜드의 정의 된 속성)의 특징으로 항상 동일한 숫자로 시작하여 동일한 시퀀스를 통과합니다.

다른 사람으로부터 자주하는 질문 Comp.Lang.C.

달리기를 가로 질러 다른 가닥을 얻으려면 다음을 시도하십시오.

#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <ctime>
#include <cstdlib>
using namespace std;
    int main  ( int arg_count, char *arg_vec[] ) {

    // most pseudo-random number generators 
    // always start with the same number and 
    // go through the same sequence. 
    // coax it to do something different!
    srand((unsigned int)time((time_t *)NULL));

    // This is reference string
    string initVec("AAAA");    
    // the family
    string DNA("ACGT");

    for (unsigned i =0; i< 5; i++) {
       string newString;
       for(unsigned j=0; j<initVec.size(); j++) {
         int dnaNo = (int)((double)rand() / ((double)RAND_MAX + 1) * 4);
         char newBase = DNA[dnaNo];         
         newString += newBase;
       }
               // ideally push in a std::set 
               // for now keep displaying everything
         if (newString != initVec) {
               cout << "Run " << i << " : " << newString << endl; 
            }
         }
     return 0;
}

다른 팁

알고리즘은 가짜입니다. 당신이 무엇을하려고하는지, 당신은 그것을하지 않고, 거기에 단일 의견이 없기 때문에, 나는 당신이 어디에서 잘못되었는지 알 수 없습니다.

내부 루프 :

for each element of initVec (4)
    create a random element
    set sameCount to 0
    if random element == current element of initVec, set sameCount to 1
    if sameCount == 4, do something (pointless as this never happens)
    add random element to newString

또한 "뉴스 스트링"은 끈이 아니라 문자열의 벡터입니다.

따라서 귀하의 문제는 사용조차 아닙니다 continue, 그것은 당신의 알고리즘이 fubar입니다.

continue 증분 부분을 건너 뛰지 않습니다 for 고리. 그 일은 직접 가서 루프의 나머지 몸체를 건너 뛰는 것입니다.

for(int i = 0; i < 10; i++)
{
  if(i == 3)
    continue;
  printf("%d ", i);
}

다음과 같습니다.

int i = 0;
while(i < 10)
{
  if(i == 3)
    goto increment;
  printf("%d ", i);
increment:
  i++;
}

에 백 슬래시가 없습니다 printf() 텍스트 편집기를 만드는 방법을 알 수 없었기 때문에 유형을 입력하겠습니다. :)

Samecount가 결코 1을 넘지 않는다는 것을 깨달았습니까? initVec.size ()가 1보다 크기 때문에 실행이 계속되지 않으므로 계속해서는 안됩니다.

int sameCount = 0;
    //sameCount is 0
    if (newBase == oldBase) { // if it is true sameCount is 1
        sameCount++;
    }
    // sameCount is 1 or 0
    if (sameCount == initVec.size()) { //this expression is always false if initVec longer than 1
        continue;
    }

다른 사람들이 이미 말했듯 이이 코드에 대한 귀하의 의도가 무엇인지 알아내는 것은 어렵습니다. 예를 들어 "완전히 다른"을 어떻게 의미합니까?

Dirkgentlys 답변은 내가 지금 말하려고했던 것에 대해 매우 포괄적입니다.

계속 사용하지 않는 것이 좋습니다. 대부분의 코딩 표준은 흐름 제어를 따라 가기가 더 어려워서 계속해서 계속 사용하는 것을 권장합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top