1. 程式人生 > >c++面試筆記2(關於main和獲取不重複的隨機數)

c++面試筆記2(關於main和獲取不重複的隨機數)

1、先於main函式執行的函式或語句,以及在main函式之後會被執行的語句。
全域性物件(會呼叫它的建構函式)在main函式之前執行,全域性物件的生命週期跨越整個程式的執行時間,優先於main函式被呼叫,同樣,全域性物件(會呼叫它的解構函式),在main函式之後執行,會在main執行完畢之後被呼叫。
給段程式碼演示一下:
#include< iostream>
#include< cstdlib>
using namespace std;
int x;
class A
{
public:
A()
{
cout<<“A 建構函式”<<endl;
cout<<“x=”<<x<<endl;
}
~A()
{
cout<<“A 解構函式”<<endl;
}
};
//A a;把這個放在main函式後面的結果是一樣的
int main()
{
cout<<“進入主函式”<<endl;
cout<<“離開主函式”<<endl;
return 0;
}
A a; //看這裡
執行結果:


在這裡插入圖片描述
2、獲取0~n之間m個不相同的隨機數(n>m,且每個n中數出現的概率相等,這m個數都不相同,也就是說m中每個元素的值都不能相同)。
這個問題讓我想到了棋牌演算法,有兩種方法:
方法一:
先直接得到一個隨機數,並把它直接賦給對應位置的陣列元素,然後再與陣列中前面元素的值進行比較,若相等,則把該位置元素對應的下標的值重新rand,重複這個步驟,最後重複上面這個步驟直到找足m個數組元素
對應的程式碼:
#include< iostream>
#include< cstdlib>
#include< ctime>
using namespace std;
int main()
{
int A[20],i;
srand((unsigned)time(NULL));
for(i=0;i<20;i++)
{
A[i]=rand()%100;
for(int j=0;j<i;j++)
if(A[i]==A[j])
{
i–;
break;
}
}
cout<<“得到20個[0,100)之間的(互不相等)隨機數”<<endl;
for(int i=0;i<20;i++)
cout<<A[i]<<" “;
cout<<endl;
return 0;
}
執行的結果:
在這裡插入圖片描述

程式分析:這種方法不是很好,但很好理解,因為當n的值很大的時候,每次判斷A[i]的值與前面的是否相等就要花費很多時間,且開銷大,它的演算法複雜度為n*m。下面再介紹第二種方法。
方法二:
初始化一個整型陣列100,每個元素的值等於其索引值(0~99),採用隨機調換位置的方法將A[rand()%100]與A[i]的值進行調換,迴圈一次調換第i個和隨機出來的索引位置的元素值(相當於洗牌)。最後隨便取其中20個元素。
實現程式碼:
#include< iostream>
#include< cstdlib>
#include< ctime>
using namespace std;
int main()
{
int a[100];
for(int i=0;i<100;i++)
a[i]=i;
srand((unsigned)time(NULL));
for(int i=0;i<20;i++)
{
int tmp=a[rand()%100];
a[rand()%100]=a[i];
a[i]=tmp;
}
for(int i=0;i<20;i++)
cout<<a[i]<<” ";
cout<<endl;
return 0;
}
實驗結果:

在這裡插入圖片描述
程式碼分析:
這種方法的演算法複雜度為m,比第一種要高很多,值得推薦。