Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2098595
  • 博文数量: 249
  • 博客积分: 1305
  • 博客等级: 军士长
  • 技术积分: 4733
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-17 10:37
个人简介

不懂的东西还有很多,随着不断的学习,不懂的东西更多,无法消灭更多不懂的东西,那就不断的充实自己吧。 欢迎关注微信公众号:菜鸟的机器学习

文章分类

全部博文(249)

文章存档

2015年(1)

2014年(4)

2013年(208)

2012年(35)

2011年(1)

分类: C/C++

2013-04-17 19:08:08


题目:

    给出一个O(n)时间的算法,在给定一个有n个不同数字的集合S以及一个正整数k<=n后,它能确定出S中最接近其中位数的k个数


思考:

    step1:求出数组的中位数的值O(n)

    step2:计算数组每个数与中位数差的绝对值,存于另一个数组B中O(n)

    step3:求出数组B中第k小的数ret O(n)

    step4:计算数组S中与中位数的差的绝对值小于ret的数并输出O(n)

    其中,step4也可以通过划分的方法找出数组S中与ret差的绝对值小于ret的数

ps:上面思路来自:http://blog.csdn.net/mishifangxiangdefeng/article/details/7689900

        
代码实现如下所示。

  1. #include <iostream>
  2. #include <ctime>

  3. using namespace std;

  4. #define MAXNUM 100

  5. /************求中位数***************/
  6. void Swap(int *a, int *b)
  7. {
  8.     int tmp = *a;
  9.     *a = *b;
  10.     *b = tmp;
  11. }

  12. //随机划分
  13. int PartitionRandom(int a[], int first, int last)
  14. {
  15.     int priot = first + rand() % (last - first + 1);
  16.     Swap(&a[first], &a[priot]);
  17.     int key = a[first];

  18.     while(first < last)
  19.     {
  20.         while(first < last && a[last] >= key)
  21.         {
  22.             last--;
  23.         }
  24.         Swap(&a[first], &a[last]);

  25.         while(first < last && a[first] <= key)
  26.         {
  27.             first++;
  28.         }
  29.         Swap(&a[first], &a[last]);
  30.     }
  31.     return first;
  32. }

  33. int Select(int a[], int first, int last , int i)
  34. {
  35.     if(first == last)
  36.     {
  37.         return a[first];
  38.     }
  39.     int priot = PartitionRandom(a, first, last);
  40.     int k = priot - first + 1;
  41.     if(k == i)
  42.     {
  43.         return a[priot];
  44.     }
  45.     if(k > i)
  46.     {
  47.         return Select(a, first, priot - 1, i);
  48.     }
  49.     else//k < i
  50.     {
  51.         return Select(a, priot + 1, last, i - k);
  52.     }
  53. }


  54. /******寻找最接近中位数的k个数*******/
  55. //length:数组的长度
  56. void FindKNums(int a[], int length, int k)
  57. {
  58.     if(k > length)
  59.     {
  60.         return;
  61.     }

  62.     //step1:求出数组的中位数的值O(n)
  63.     int mid = Select(a, 0, length - 1, length / 2);
  64.     
  65.     cout << "mid = " << mid << endl;

  66.     //step2:计算数组每个数与中位数差的绝对值,存于另一个数组B中O(n)
  67.     int *b = (int *)malloc(sizeof(int) * length);
  68.     if(b == NULL)
  69.     {
  70.         return;
  71.     }
  72.     
  73.     for(int i = 0; i < length; i++)
  74.     {
  75.         b[i] = (int)fabs(double(a[i] - mid));
  76.     }

  77.     //step3:求出数组B中第k小的数ret O(n)
  78.     int ret = Select(b, 0, length - 1, k);

  79.     cout << "ret = " << ret << endl;

  80.     //step4:计算数组S中与中位数的差的绝对值小于ret的数并输出O(n)
  81.     for(int i = 0; i < length; i++)
  82.     {
  83.         int tmp = (int)fabs(double(a[i] - mid));
  84.         if(tmp <= ret)
  85.         {
  86.             cout << a[i] << " ";
  87.         }
  88.     }
  89.     cout << endl;

  90.     


  91. }
  92. int main(int argc, char* argv[])
  93. {
  94.     int a[MAXNUM];
  95.     int length;
  96.     int k;
  97.     cout << "输入数组中元素的个数:";
  98.     cin >> length;
  99.     cout << "输入查找最接近中位数的个数:";
  100.     cin >> k;
  101.     //随机产生数组元素
  102.     srand((unsigned)time(NULL));
  103.     for(int i = 0; i < length; i++)
  104.     {
  105.         a[i] = rand() % 100 - 1;
  106.     }
  107.     cout << "产生的元素为:" << endl;
  108.     for(int i = 0; i < length; i++)
  109.     {
  110.         cout << a[i] << " ";
  111.     }
  112.     cout << endl;
  113.     FindKNums(a, length, k);
  114.     return 0;
  115. }
   





            

                                                    梦醒潇湘love
                                            2013年4月17日 19:05

阅读(1598) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~