免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: BuTa丶潇
打印 上一主题 下一主题

[算法] 昨天面试的一道上机笔试题,哪位朋友有好的思路吗? [复制链接]

论坛徽章:
0
21 [报告]
发表于 2013-04-04 17:57 |只看该作者
肯定是个学汇编出身的,连下标都讲出来了

论坛徽章:
5
丑牛
日期:2014-01-21 08:26:26卯兔
日期:2014-03-11 06:37:43天秤座
日期:2014-03-25 08:52:52寅虎
日期:2014-04-19 11:39:48午马
日期:2014-08-06 03:56:58
22 [报告]
发表于 2013-04-05 14:48 |只看该作者
挺不错的了,支持。

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
23 [报告]
发表于 2013-04-07 09:49 |只看该作者
回复 11# BuTa丶潇
用equal_range的话,我写个demo
如果你的编译器支持最新的C++标准,那么
  1. #include <vector>
  2. #include <algorithm>
  3. #include <iostream>
  4. using namespace std;

  5. void foo( const double* buf, size_t n, double a, double b )
  6. {
  7.     std::pair<const double*,const double*> range = std::equal_range( buf+0, buf+n, a
  8.         , [a,b](double e1, double e2) {
  9.             int v1 = e1<a ? -1 : ( e1<=b ? 0 : 1 );
  10.             int v2 = e2<a ? -1 : ( e2<=b ? 0 : 1 );
  11.             return v1 < v2;
  12.         } );

  13.     if( range.first == range.second )
  14.     {
  15.         std::cout << "不存在" << std::endl;
  16.         return;
  17.     }

  18.     std::cout << (range.first-buf) << " - " << (range.second-buf-1) << std::endl;
  19. }

  20. template<size_t N>
  21. inline void foo( const double (&buf)[N], double a, double b )
  22. {
  23.     foo( buf, N, a, b );
  24. }

  25. int main()
  26. {
  27.     double buf[] = { 3 , 3.5 , 5.7 , 6.8 , 11 , 15.4 };

  28.     foo( buf, 0.3, 10 ); // 0-3
  29.     foo( buf, 1, 2 ); //
  30.     foo( buf, 19.4, 22 ); //
  31.     foo( buf, 3.5, 17 ); // 1-5

  32.     return 0;
  33. }
复制代码
如果你的编译器比较老旧,用
  1. #include <vector>
  2. #include <algorithm>
  3. #include <iostream>
  4. using namespace std;

  5. struct ablesser_
  6. {
  7.     ablesser_( double a, double b ) : a_(a), b_(b)
  8.     {
  9.     }

  10.     bool operator()( double e1, double e2 ) const
  11.     {
  12.         int v1 = e1<a_ ? -1 : ( e1<=b_ ? 0 : 1 );
  13.         int v2 = e2<a_ ? -1 : ( e2<=b_ ? 0 : 1 );
  14.         return v1 < v2;
  15.     }

  16.     double a_, b_;
  17. };

  18. void foo( const double* buf, size_t n, double a, double b )
  19. {
  20.     std::pair<const double*,const double*> range = std::equal_range( buf+0, buf+n, a, ablesser_(a,b) );

  21.     if( range.first == range.second )
  22.     {
  23.         std::cout << "不存在" << std::endl;
  24.         return;
  25.     }

  26.     std::cout << (range.first-buf) << " - " << (range.second-buf-1) << std::endl;
  27. }

  28. template<size_t N>
  29. inline void foo( const double (&buf)[N], double a, double b )
  30. {
  31.     foo( buf, N, a, b );
  32. }

  33. int main()
  34. {
  35.     double buf[] = { 3 , 3.5 , 5.7 , 6.8 , 11 , 15.4 };

  36.     foo( buf, 0.3, 10 ); // 0-3
  37.     foo( buf, 1, 2 ); //
  38.     foo( buf, 19.4, 22 ); //
  39.     foo( buf, 3.5, 17 ); // 1-5

  40.     return 0;
  41. }
复制代码
当然,代码都有些晦涩,最佳的办法应该是调用 std::lower_bound 获得第一个下标,std::upper_bound  获得第二个下标(其实你要的是这个值之前一位置)

论坛徽章:
0
24 [报告]
发表于 2013-04-07 17:39 |只看该作者
本帖最后由 BuTa丶潇 于 2013-04-07 17:42 编辑

回复 23# bruceteen


    十分感谢!!{:3_193:}

我在你的基础上,也尝试了下代码:

  1. #include<iostream>
  2. #include <vector>
  3. using namespace std;
  4. /*找出满足这个区间的数据在数组里面的下标*/
  5. void range(vector<double> &nums,const double & a,const double & b){
  6.         if( b < *nums.begin() || a > nums.back() ) {
  7.                 cout <<"a=" << a << ",b=" << b << " , no fits!"<< endl;
  8.                 exit(0);
  9.         } else {
  10.                 pair<vector<double>::iterator,vector<double>::iterator> range_a , range_b ;
  11.                 range_a = equal_range(nums.begin(),nums.end(),a);
  12.                 range_b = equal_range(nums.begin(),nums.end(),b);
  13.                 cout<<range_a.first-nums.begin()<<'-'<<range_b.second-nums.begin()-1<<endl;
  14.         }//得到a,b的查找位置.
  15. }
  16. int main(void) {
  17.         double array[4]={1.5,2.6,2.6,3.7};//测试数据
  18.         vector<double> nums;
  19.         for(int i=0;i<3;i++)
  20.                 nums.push_back(array[i]);
  21.         range (nums,   0, 3.2);//a=0,b=3.2 测试区间[0,3.2]        res->0-1
  22.         range (nums, 5.3, 9.2);//测试区间[5.3,9.2]                        res->none
  23.         return 0;
  24. }
复制代码
总之学到了很多东西..再次感谢!!

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
25 [报告]
发表于 2013-04-08 09:46 |只看该作者
回复 24# BuTa丶潇
这……,我用lower_bound/upper_bound重写吧

若你的编译器支持C++11标准
  1. #include <vector>
  2. #include <algorithm>
  3. #include <iostream>

  4. void range( const std::vector<double>& buf, double a, double b )
  5. {
  6.     auto p1 = std::lower_bound( buf.begin(), buf.end(), a );
  7.     auto p2 = std::upper_bound( buf.begin(), buf.end(), b );

  8.     if( p1 == p2 )
  9.         std::cout << "a=" << a << ", b=" << b << ", no fits!" << std::endl;
  10.     else
  11.         std::cout << std::distance(buf.begin(),p1) << '-' << std::distance(buf.begin(),p2)-1 << std::endl;
  12. }

  13. using namespace std;

  14. int main()
  15. {
  16.     vector<double> nums = { 1.5, 2.6, 2.6, 3.7 };//测试数据
  17.     range( nums,   0, 3.2 ); // 0-2
  18.     range( nums, 5.3, 9.2 ); // no fits

  19.     return 0;
  20. }
复制代码
若你的编译器不支持C++11标准
  1. #include <vector>
  2. #include <algorithm>
  3. #include <iostream>

  4. void range( const std::vector<double>& buf, double a, double b )
  5. {
  6.     std::vector<double>::const_iterator p1 = std::lower_bound( buf.begin(), buf.end(), a );
  7.     std::vector<double>::const_iterator p2 = std::upper_bound( buf.begin(), buf.end(), b );

  8.     if( p1 == p2 )
  9.         std::cout << "a=" << a << ", b=" << b << ", no fits!" << std::endl;
  10.     else
  11.         std::cout << std::distance(buf.begin(),p1) << '-' << std::distance(buf.begin(),p2)-1 << std::endl;
  12. }

  13. using namespace std;

  14. int main()
  15. {
  16.     vector<double> nums;
  17.     {
  18.         const double array[] = { 1.5, 2.6, 2.6, 3.7 }; // 测试数据
  19.         const size_t len = sizeof(array)/sizeof(array[0]);
  20.         nums.reserve( len );
  21.         for( size_t i=0; i<len; ++i )
  22.             nums.push_back( array[i] );
  23.     }
  24.     range( nums,   0, 3.2 ); // 0-2
  25.     range( nums, 5.3, 9.2 ); // no fits

  26.     return 0;
  27. }
复制代码

论坛徽章:
0
26 [报告]
发表于 2013-04-08 11:14 |只看该作者
创建结构体,struct data {int   cnt,double data_value}
存储原数组下标与值  耗时n
遍历原数组,取值大于后等于a的最接近值x,小于或等于b的最接近值y  耗时2n
qsort  struct data    对数级
bsearch struct data   x对数级
bsearch struct data   y对数级
取出  x,y之间的所有data.cnt  n
耗时5n左右


论坛徽章:
0
27 [报告]
发表于 2013-04-08 19:57 |只看该作者
3楼正解

论坛徽章:
0
28 [报告]
发表于 2013-05-09 09:19 |只看该作者
如果只有几个[a, b]需要输出,直接for(i=0;i<n;++i)if()else 复杂度O(k*n)
如果[a, b]较多,排序+二分,复杂度O(k * nlogn)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP