(1)選擇第K個小的數
該問題就是找出排序中排名第k的數,其實是一種排序的變相問法,當然這個問題可以用堆排序解決,能不能有別的排序也能解決?快排同樣也能。
只要每次判斷當前是第幾個位置,如果等於k,則找到所求數,返回。
下面只是給個樣例,程序不保證絕對正確哈
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int find_kth(int* arr, int l, int h, int k);
int rand_int(int l, int h);
void swap(int* arr, int i, int j);
int main(int argc, char* argv[]){
int num = argc-2;
int arr[num];
for(int i=0; i<num; i++){
arr[i] = atoi(argv[i+1]);
}
int k = atoi(argv[argc-1]);
cout<<find_kth(arr, 0, num-1, k)<<endl;
return 0;
}
int find_kth(int* arr, int l, int h, int k){
if (l>h)
return -1;
if (l==h && l==k)
return arr[l];
// rand select one element
int r = rand_int(l, h);
swap(arr, l, r);
// qsort to find k-th
int x = arr[l];
int i = l;
int j = h;
while(i<j){
while(i<j && arr[j]>=x)
j--;
if(i<j){
arr[i] = arr[j];
i++;
}
while(i<j && arr[i]<x)
i++;
if(i<j){
arr[j] = arr[i];
j--;
}
}
arr[i] = x;
if(i == k)
return arr[k];
else if (k>i)
return find_kth(arr, i+1, h, k);
else
return find_kth(arr, l, i-1, k);
}
void swap(int* arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
int rand_int(int l, int h){
srand((unsigned int)time(0));
int r = rand()%(h-l+1);
return l+r;
}
(2)隨機取數字,希望給的數字按照升序排序。在[0,n]區間去m個數字。
這裏給了個概率的方法,保證升序取出,同時也能保證概率隨着個數變化。
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int main(int argc, char* argv[]){
srand((unsigned int)time(0));
if(argc != 3){
cout<<"Usage rand_select n m\n This program will select m number from[0, n]"<<endl;
return -1;
}
int n = atoi(argv[1]);
int m = atoi(argv[2]);
for(int i=0; i<n; i++){
if(rand()%(n-i) < m){
m--;
cout<<i<<endl;
}
}
}