常用算法(2)

(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;
    }
  }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章