下面的问题是我在此wiki page上遇到的一个问题。
我的算法:
工资低于男性,增加结婚柜台。设置双方女性
并将男性
isMarried
值设置为true。 低于未婚女性的最低工资。
这是我的实现:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
srand(time(NULL));
int min = 1;
int max = 1000000;
Male male[100];
Female female[100];
double count = 0;
bool done = false;
//Fill array of Females and Males with random salaries ranging from 1 to 10
for(int i=0; i<100; i++){
int output = min + (rand() % (int)(max - min + 1));
male[i].salary = output;
}
for(int i=0; i<100; i++){
int output = min + (rand() % (int)(max - min + 1));
female[i].salary = output;
}
//Start dating
//Keep dating until the maximum salary of males is lower than minimum salary of females
do{
random_shuffle(begin(male), end(male)); //Shuffle array of males
random_shuffle(begin(female), end(female)); //Shuffle array of females
for(int i=0; i<100; i++){ //Compare a female and male from both arrays
if(female[i].salary < male[i].salary)
if(!female[i].isMarried && !male[i].isMarried){
count++;
female[i].isMarried = true;
male[i].isMarried = true;
cout << "Female salary: " << female[i].salary << endl;
cout << "Male salary: " << male[i].salary << endl;
}
}
int maxMen = 0;
for(int i=0; i<100; i++){
if(male[i].salary > maxMen && !male[i].isMarried)
maxMen = male[i].salary;
}
int minWomen = 1000000;
for(int i=0; i<100; i++){
if(female[i].salary < minWomen && !female[i].isMarried)
minWomen = female[i].salary;
}
if(maxMen <= minWomen)
done = true;
}while(!done);
cout << "Percentage: " << count/100;
cout << endl;
int unmarried = 0;
cout << "Number of unmarried females: ";
for(int i=0; i<100; i++)
if(!female[i].isMarried)
unmarried++;
cout << unmarried << endl;
unmarried = 0;
cout << "Number of unmarried males: ";
for(int i=0; i<100; i++)
if(!male[i].isMarried)
unmarried++;
cout << unmarried << endl;
cout << endl;
return a.exec();
}
我在Programmers.SE,显然是I should be getting 68%上问了这个问题。
我得到的百分比值范围从35%到40%。我究竟做错了什么?
最佳答案
1)您的条件变量已统一化:
bool done=false;
这可能会导致循环比计划的更早退出,因为只有在
maxMen < minWomen
时才将其设置为可预测的值。2)您的结束条件设置不正确:
您只有在
maxMen < minWomen
时才完成。但是,如果maxMen == minWomen
没有女人可以结婚了,那么您将陷入无限循环。如果您的工资规模很小,这种现象很可能发生。如果从1到1000,这种情况的可能性较小。但是为了避免不可能的情况,将该子句更改为: if (maxMen <= minWomen) // no new wedding in sight
done = true;
结合先前的问题,您的循环条件是错误的。只要未完成,就应该循环播放(如果maxMen> minWomen,则仍然可以进行婚礼)。因此,将其重写为:
...
} while (! done);
结论
通过这3个更改,当我几次重新运行程序时,我得到的百分比从55%到74%,大多数值在65%到70%之间。
其他建议
您应该避免使用硬编码数字。代替
10
,但更喜欢max+1
。在开头const int N=100;
定义,然后将所有文字100
替换为N
。这样,更容易使用模拟参数(使用不同的薪水范围或更大的人口)。您可以将模拟放在返回百分比作为值的单独函数中,然后在
main()
中多次运行模拟(100,1000?),计算百分比的平均值和标准偏差。与手动运行和粗略估计相比,这提供了更准确的结果。如果您对模拟感兴趣,那么值得一看
<random>
:它提供了多种随机生成器和随机分布的选择,比rand()功能强大得多。例子: mt19937 generator(time(NULL)); // mersene twister generator seeded with time
...
uniform_int_distribution<int> distribution(min, max); // after declaration of your min and max
...
male[i].salary = distribution(generator); // and same for female
顺便说一句,您可能对
std::count_if
, std::min()
和std::max()
感兴趣,它们可以轻松地节省for循环的重复编码。