如何在C ++中重新启动循环(通过随机运行查找唯一序列) [英] Howto Restart Loop in C++ (Finding Unique Sequence Over Random Runs)

查看:104
本文介绍了如何在C ++中重新启动循环(通过随机运行查找唯一序列)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码尝试在K次运行中生成随机字符串. 但是我们希望新生成的字符串完全不同 及其参考字符串.

The following codes try to generate random strings over K runs. But we want the newly generated strings to be totally different with its reference string.

为此,我尝试使用继续"重新启动随机 字符串生成过程.但是,它似乎不起作用. 我下面的方法有什么问题?

For that I tried to use "continue" to restart the random string generation process. However it doesn't seem to work. What's wrong with my approach below?

#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相同,对吗?在将其推入或打印到控制台之前,将进行简单的比较.

Your code looks fine on first glance, unless I am missing a big part of your requirements. Read this before you use rand(). Except of course, the continue part. What you are trying to do is see if this is the same as the initVector or not, right? A simple comparison would do before you push it in or print to the console.

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;
}

每次在newString中创建新条目时,都会初始化sameCount变量,并在for循环的结尾}超出范围.因此,它将不会增加以充当对重复生成的正确检查.理想情况下,应使用std::set并继续插入其中.不允许重复,这样可以避免麻烦.

The sameCount variable is initialized each time you create a new entry to the newString and goes out of scope at the closing } of the for loop. So, it will not be incremented to function as a proper check against duplicate generation. You should ideally, use a std::set and keep inserting in it. Duplicates are not allowed and you are saved from a lot of trouble.

有关使用rand() srand()和随机数生成的更多信息:

More on using rand() srand() and random number generation:

通过comp.lang.c常见问题解答:

From the comp.lang.c FAQ:

[...]许多随机数生成器的低阶位令人痛苦地是非随机​​的

[...]the low-order bits of many random number generators are distressingly non-random

如果您希望将随机数保持在该范围内

If you want to keep your randome numbers in the range

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

与简单的rand() % N(在链接中建议)相比,

一种更好的方法是使用以下内容:

a better method compared to the simple rand() % N (as advised in the link) is to use the following:

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

现在,如果您要运行程序,则每次将获得10000条奇数随机DNA链的相同集合.原来这是因为:

Now, if you were to run your program, every time you will get the same set of 10000 odd random DNA strands. Turns out this is because:

大多数伪随机数生成器(和C库rand的已定义属性)的一个特征是,它们始终以相同的数字开头并经历相同的序列.

It's a characteristic of most pseudo-random number generators (and a defined property of the C library rand) that they always start with the same number and go through the same sequence.

来自comp.lang.c的另一个常见问题解答.

from another FAQ of comp.lang.c.

要获得不同的结果,请尝试以下操作:

To get different strands across runs try the following:

#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;
}

这篇关于如何在C ++中重新启动循环(通过随机运行查找唯一序列)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆