1

以下代码尝试在 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;
}
4

5 回答 5

4

乍一看,您的代码看起来不错,除非我遗漏了您的大部分要求。使用前请阅读rand()内容。当然,这continue部分除外。您要做的是查看这是否与 the 相同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结束时超出范围。因此,它不会增加以作为对重复生成的适当检查。理想情况下,您应该使用 a并继续插入其中。不允许重复,您可以避免很多麻烦。}forstd::set

更多关于使用rand() srand()和随机数生成:

从 comp.lang.c 常见问题解答:

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

如果您想将随机数保持在范围内

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

与简单(如链接中所建议的)相比,更好的方法rand() % N是使用以下方法:

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

现在,如果你要运行你的程序,每次你都会得到相同的一组 10000 奇数个随机 DNA 链。原来这是因为:

大多数伪随机数生成器(以及 C 库 rand 的定义属性)的一个特征是它们总是以相同的数字开始并经过相同的序列。

来自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;
}
于 2009-03-05T08:59:59.497 回答
2

你的算法是假的。无论你想做什么,你都没有做,因为那里没有一条评论,我真的不知道你哪里出错了。

你的内循环:

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

除此之外,您的“newString”根本不是字符串,而是字符串向量。

所以,你的问题甚至不是使用continue,而是你的算法是 FUBAR。

于 2009-03-05T09:40:01.600 回答
1

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()因为我不知道如何让文本编辑器让我输入一个。:)

于 2009-03-05T08:59:51.663 回答
1

对于我现在要说的内容,dirkgentlys 的回答非常全面。

不过,我建议您不要使用 continue,大多数编码标准都建议不要使用 continue,因为它使流程控制更难遵循。

于 2009-03-05T09:08:39.257 回答
1

您是否意识到 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;
    }

正如其他人已经说过的那样,很难找出你对这段代码的意图。您能否告诉我们,例如,“完全不同”是什么意思?

于 2009-03-05T09:42:24.510 回答