如何在C ++中重新启动循环(通过随机运行查找唯一序列) [英] Howto Restart Loop in C++ (Finding Unique Sequence Over Random Runs)
问题描述
以下代码尝试在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屋!