常用算法(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;
    }
  }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值