如何加速我的C ++程序?

时间:2015-03-04 23:39:08

标签: c++ optimization vector

基本上我正在重新学习C ++并决定创建一个乐透号码生成器。 代码创建故障单,如果该故障单尚不存在,则会将其添加到矢量中以存储每个可能的组合。

该程序有效,但它的速度太慢,大约每秒都会添加一个条目,而且它会变得更慢,因为它发现在超过1300万种可能的组合中添加独特的组合更加困难。

无论如何这里是我的代码,任何优化提示都会赞赏:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>

using namespace std;

vector<string> lottoCombos;

const int NUMBERS_PER_TICKET = 6;
const int NUMBERS = 49;
const int POSSIBLE_COMBOS = 13983816;

string createTicket();
void startUp();
void getAllCombinations();

int main()
{
    lottoCombos.reserve(POSSIBLE_COMBOS);
    cout<< "Random Ticket: "<< createTicket()<< endl;

    getAllCombinations();

    for (int i = 0; i < POSSIBLE_COMBOS; i++)
    {
        cout << endl << lottoCombos[i];
    }

    system("PAUSE");
    return 0;
}

string createTicket()
{
    srand(static_cast<unsigned int>(time(0)));
    vector<int> ticket;
    vector<int> numbers;
    vector<int>::iterator numberIterator;

    //ADD AVAILABLE NUMBERS TO VECTOR
    for (int i = 0; i < NUMBERS; i++)
    {
        numbers.push_back(i + 1);
    }

    for (int j = 0; j < NUMBERS_PER_TICKET; j++)
    {
        int ticketNumber = rand() % numbers.size();
        numberIterator = numbers.begin()+ ticketNumber;
        int nm = *numberIterator;
        numbers.erase(numberIterator);
        ticket.push_back(nm);
    }
    sort(ticket.begin(), ticket.end());

    string result;
    ostringstream convert;
    convert << ticket[0] << ", " << ticket[1] << ", " << ticket[2] << ", " << ticket[3] << ", " << ticket[4] << ", " << ticket[5];
    result = convert.str();

    return result;
}

void getAllCombinations()
{
    int i = 0;
    cout << "Max Vector Size: " << lottoCombos.max_size() << endl;
    cout << "Creating Entries" << endl;

    while ( i != POSSIBLE_COMBOS )
    {
        bool matchFound = true;
        string newNumbers = createTicket();

        for (int j = 0; j < lottoCombos.size(); j++)
        {
            if ( newNumbers == lottoCombos[j] )
            {
                matchFound = false;
                break;
            }
        }

        if (matchFound != false)
        {
            lottoCombos.push_back(createTicket());
            i++;
            cout << "Entries: "<< i << endl;
        }
    }
    sort(lottoCombos.begin(), lottoCombos.end());
    cout << "\nCombination generation complete!!!\n\n";
}

1 个答案:

答案 0 :(得分:1)

每张彩票生成一秒钟的原因是因为你误用了srand()。通过每次调用createTicket()时调用srand(time(0)),确保createTicket()在每次调用时返回相同的数字,直到下次time()返回的值发生变化,即每秒一次。所以你的reject-duplicates算法几乎总能找到一个副本,直到下一秒过去。你应该将你的srand(time(0))调用移到main()的顶部。

也就是说,这里可能存在更大的问题:我的第一个问题是,是否真的有必要生成并存储每一张可能的彩票? (如果是这样,为什么?)IIRC真正的彩票在发票时不这样做;他们只是生成一些随机数字并将其打印出来(如果有多张中奖彩票打印有相同的号码,这些彩票的所有者将分享奖金)。

假设您确实需要出于某种原因生成所有可能的彩票,那么有更好的方法可以比随机方式更好。如果您在驾驶汽车时曾经看过里程表的增量,那么您将会想到如何线性地完成它;想象一下带有6个轮子的里程表,每个轮子有49个不同的可能位置(而不是传统的10个)。

最后,一个向量具有O(N)查找时间,如果你在向量中为你生成的每个值进行查找,那么你的算法有O(N ^ 2)时间,也就是说,它正在进行当你生成更多门票时,真的很快变得非常慢。因此,如果您必须将所有已知票证存储在数据结构中,您肯定应该使用具有更快查找时间的数据结构,例如std :: map或std :: unordered_set,或者甚至是std :: bitset,如@RedAlert。

相关问题