非常慢的随机字符串生成器

时间:2012-08-11 12:52:00

标签: c++

我想出了下面的代码来生成100001个随机字符串。字符串应该是唯一的。但是,以下代码需要数小时才能完成这项工作。有人能告诉我如何优化它,为什么它如此缓慢?

string getRandomString(int length) {     
    static string charset = "abcdefghijklmnopqrstuvwxyz";   
    string result;
    result.resize(length);
    for (int i = 0; i < length; i++) {
        result[i] = charset[rand() % charset.length()];   
    }
    return result; 
} 
void main(){

    srand(time(NULL));
    vector<string> storeUnigrams;
    int numUnigram = 100001; 
    string temp = "";
    int minLen = 3;
    int maxLen = 26;
    int range = maxLen - minLen + 1;
    int i =0;

    while(i < numUnigram){
        int lenOfRanString = rand()%range   + minLen;
        temp = getRandomString(lenOfRanString);
        bool doesithave = false;
        for(int j =0 ; j < storeUnigrams.size() ; j++){
            if(temp.compare(storeUnigrams[j]) == 0){
                doesithave = true;
                break;
            }
            if(temp.compare(storeUnigrams[j]) < 0){
                break;
            }
        }
        if(!doesithave){
            storeUnigrams.push_back(temp);
            sort(storeUnigrams.begin(),storeUnigrams.end());
            i++;
        }

    }

5 个答案:

答案 0 :(得分:9)

有两个因素导致代码变慢:

  1. 通过线性搜索检查字符串是否已存在 - O(n)
  2. 在每次迭代中对矢量进行排序 - O(n log n)
  3. 使用例如用于存储字符串的set - 它是自动排序的,检查是否存在很快:

    int main(){
    
        srand(time(NULL));
        set<string> storeUnigrams;
        int numUnigram = 100001; 
        int minLen = 3;
        int maxLen = 26;
        int range = maxLen - minLen + 1;
    
        while(storeUnigrams.size() < numUnigram){
            int lenOfRanString = rand()%range   + minLen;
            storeUnigrams.insert(getRandomString(lenOfRanString));
        }
    }
    

答案 1 :(得分:0)

菲利普回答很好。另一种方法是使用Self-balancing Binary Search Tree之类的Red Black Tree而不是Vector。您可以在log(n)时间内执行搜索和插入。如果搜索为空,请插入元素。

答案 2 :(得分:0)

此代码仅生成一次唯一的随机数,并将其存储在random_once[i]中。

第一个for循环生成广告存储随机数。

第二个for循环用于获取存储在random_once[i]数组中的预渲染随机数。

是生成100001随机数,如果不是几天,则需要数小时。

#include <ctime>
#include <iostream>
using namespace std;


int main()
{
      int numUnigram = 3001;
      int size=numUnigram;
      int random_once[100001];

      cout<<"Please wait: Generatng "<<numUnigram<<" random numbers   ";
      std::cout << '-' << std::flush;
      srand(time(0));



      for (int i=0;i<size;i++)  

      {

           //This code generates a unique random number only once
           //and stores it in random_once[i]

            random_once[i]=rand() % size;
            for(int j=0;j<i;j++) if (random_once[j]==random_once[i]) i--; 

            //loading animation  
            std::cout << "\b\\" << std::flush;
            std::cout << "\b|" << std::flush;
            std::cout << "\b/" << std::flush;
            std::cout << "\b-" << std::flush;

      }

      cout<<" \n";

      // this code dispays unique random numbers stored in random_once[i]
      for ( i=0;i<size;i++) cout<<" "<<random_once[i]<<"\t";
      cout<<" \n";

  return 0;
}

答案 3 :(得分:-1)

在while循环之外定义变量 - 因为它们在每次迭代时都被重新定义

int lenOfRanString = rand()%range   + minLen; ;
bool doesithave = false;

<强>更新

在许多书籍中都有人建议,在所有新编译器的实践中,这不会显着提高性能

答案 4 :(得分:-2)

使用char数组而不是字符串(字符串类在幕后做很多事情)