当前位置: 首页 > news >正文

东莞网站设计与网站制作/全球网站排名查询网

东莞网站设计与网站制作,全球网站排名查询网,wordpress多张页面左右滑动,网站推广费用大概需要多少钱题目链接在&#xff1a;针对一群范围对的最快查找算法设计&#xff08;不要用数组&#xff09;。是我眼下遇到的一个较棘手的问题。 描写叙述例如以下&#xff1a; 假如有一群范围对&#xff0c;格式为&#xff1a;<范围表示&#xff0c;该范围相应的结果值>&#xff0c;…

题目链接在:针对一群范围对的最快查找算法设计(不要用数组)。是我眼下遇到的一个较棘手的问题。

描写叙述例如以下:

假如有一群范围对,格式为:<范围表示,该范围相应的结果值>,设计一个最快查找算法。使得给定一个值。输出该值所在范围对的结果值。
注意:范围对之间没有交集,即不可能存在<1, 10>和<2, 11>这种两个范围对。



比如有下面几个范围对:
<<1, 2>, 20>
<<3, 37>, 27>
<<48, 57>, 28>
<<58, 63>, 27>
<<97, 128>, 122>
<<129, 149>, 12>
<<150, 189>, 13>
<<200, 245>, 14>
<<246, 256>, 129>
<<479, 560>, 12>

假如给定一个数100,则依据题意应输出122,由于100属于范围对<97, 128>

要求:不要用范围对作为下标用数组来存储,由于范围对可能很大。

对于这个问题,思考许久。有了以下几个思路


1. 用STL map来存储这些范围对(key)及相应的结果集(value),用map进行查找

范围对定义例如以下:

复制代码
class range {
public:int from;                                                                  int to; public:range(): from(-1), to(-1) {}range(int f, int t): from(f), to(t) {}
};
复制代码

map定义为:

typedef map<range*, int> range_map;

但这里有个问题,map的key是自己定义类型,一般须要自己定义比較函数才干进行查找。一般的自己定义比較函数例如以下:

struct cmp_func {bool operator()(const range* lc,const range* rc) const {return (lc->from < rc->from) || (lc->from == rc->from && lc->to < rc->to);}
};

但这种比較函数并不适用于我们的需求,由于我们要求查询的并非一个范围对,即并非查询map中有没有<3, 37>这种范围对。而是要求给定一个值。查询这个值属于哪个范围对。那么能不能自己定义一个这种比較函数呢?以上面那个样例为例,假设我们查找35这个数,我们将35包装成一个范围对<35, 35>。然后查找它包括在map中的哪个范围对。上面的样例是包括在<3, 37>这种范围对。这样就找到了。也就是两个key相等,仅仅要它们包括在同一个范围对就可以。这似乎有点奇怪。违背了通常意义上的比較含义(也就是两个key相等,两个key的组成部分都应该同样才是)。无论怎样,这种比較函数还是比較简单的,例如以下:

struct cmp_func {bool operator()(const range* lc,const range* rc) const {return lc->to < rc->from;}
};

这样就实现了我们用map的find函数来查找给定的一个数属于哪个范围对了。

当然,这时我们的map定义就变成了:

typedef map<range*, int, cmp_func> range_map;

用map查找表面上看上去应该挺高效的,至少比一个个顺序查找要快吧。但事实却并不是如此。

我用未自己定义比較函数的map顺序查找和自己定义上面比較函数的map find查找,结果却发现用自己定义比較函数后的效果并不好,居然比顺序查找还要慢,以下的粗糙的測试程序:

复制代码
#include<iostream>
#include<stdio.h>
#include<map>
#include<sys/time.h>
using namespace std;class range {
public:int from;                                                                  int to; public:range(): from(-1), to(-1) {}range(int f, int t): from(f), to(t) {}
};struct cmp_func {bool operator()(const range* lc,const range* rc) const {return lc->to < rc->from;}
};typedef map<range*, int, cmp_func> range_map;int get_next1(range_map *rm, int c) {for(range_map::iterator it = rm->begin(); it != rm->end(); ++it) {if(c >= it->first->from && c <= it->first->to) return it->second;}return -1; // not found.
}int get_next2(range_map *rm, int c) {range_map::iterator iter = rm->find(new range(c, c));if(iter != rm->end())  return iter->second;return -1;  // not found.
}int main()
{struct timeval t_begin, t_end;range_map *rm = new range_map();rm->insert(pair<range*, int>(new range(1, 2), 20));rm->insert(pair<range*, int>(new range(3, 37), 27));rm->insert(pair<range*, int>(new range(48, 57), 28));rm->insert(pair<range*, int>(new range(58, 63), 27));rm->insert(pair<range*, int>(new range(97, 128), 122));rm->insert(pair<range*, int>(new range(129, 149), 12));rm->insert(pair<range*, int>(new range(150, 189), 12));rm->insert(pair<range*, int>(new range(200, 245), 14));rm->insert(pair<range*, int>(new range(246, 256), 129));rm->insert(pair<range*, int>(new range(479, 560), 12));gettimeofday(&t_begin,NULL);int result[256];for(int c = 0; c < 256; c++)result[c] = get_next1(rm, c);gettimeofday(&t_end,NULL);double timeuse=1000000*(t_end.tv_sec-t_begin.tv_sec)+(t_end.tv_usec-t_begin.tv_usec);timeuse/=1000000;printf("\nget_next1 time use: %.12f\n", timeuse);for(int c = 0; c < 256; c++)cout << result[c] << " ";cout << endl;gettimeofday(&t_begin,NULL);for(int c = 0; c < 256; c++)result[c] = get_next2(rm, c);gettimeofday(&t_end,NULL);timeuse=1000000*(t_end.tv_sec-t_begin.tv_sec)+(t_end.tv_usec-t_begin.tv_usec);timeuse/=1000000;printf("\nget_next2 time use: %.12f\n", timeuse);for(int c = 0; c < 256; c++)cout << result[c] << " ";cout << endl;return 0;
}
复制代码

执行结果为:

get_next1 time use: 0.000124000000
get_next2 time use: 0.000144000000

当然这个样例并不能代表全部情况。且每次执行结果也不一样,但从每次的执行结果来看,差点儿没有一次是用自己定义比較函数比顺序查找情况好的。

这至少说明了一点:我们的自己定义比較函数让map在查找时做了一些额外的工作,减慢了速度。比方我们为了使用map的find函数,不得不封装我们的一个数为一个range对象,在查找的时候还得调用我们自己定义的比較函数进行处理。

难道就仅仅能顺序查找吗?在这个不靠谱的思路过后又萌生了还有一个不靠谱的思路。

 

2. 使用二分查找的思想来查找范围对

我们使用ranges和results这两个数组来保存范围对及相应的结果,按序保存,每两个ranges数相应一个results里的数。

比如上面的样例保存为:

int ranges[] = {1, 2, 3, 37, 48, 57, 58, 63, 97, 128, 129, 149, 150, 189, 200, 245, 246, 256, 479, 560};
int results[] = {20, 27, 28, 27, 122, 12, 13, 14, 129, 12};

使用二分查找来查找某个数属于哪个范围对。那么怎样查找呢?比方查找35属于哪个范围对,首先与最中间的128进行比較,35<128。这时候有两种可能:

(1)100在128前半部分的数组里,即1, 2, 3, 37, 48, 57, 58, 63, 97;

(2)因为128是范围对<97, 128>的第二部分,那么也有可能这个数属于这个范围对。

因为35不属于这个范围对。那么仅仅有在97之前的部分找(不包含97),继续二分即与37进行比較。35 < 37,与上类似,此时35属于范围对<3, 37>,也就是找到了。

再举个样例。找130属于哪个范围对,相同的先与128比較。130 > 128,这时候130仅仅可能在128的后半部分而不须要推断是否属于范围对<128, 129>,由于<128, 129>不是范围对。

怎么推断是不是范围对呢?非常easy,依据当前位置的奇偶性推断就可以。

以下是我写的二分查找算法,及与map顺序查找、数组顺序查找的简单对照试验:

复制代码
#include<iostream>
#include<stdio.h>
#include<map>
#include<sys/time.h>
using namespace std;class range {
public:int from;                                                                  int to; public:range(): from(-1), to(-1) {}range(int f, int t): from(f), to(t) {}
};typedef map<range*, int> range_map;int get_next1(range_map *rm, int c) {for(range_map::iterator it = rm->begin(); it != rm->end(); ++it) {if(c >= it->first->from && c <= it->first->to) return it->second;}return -1; // not found.
}

// binary search
int get_next2(int *ranges, int *results, int size, int c) {if(size <= 1) return -1;int start, end, mid;start = 0;end = size - 1;while(start <= end) {if(c < ranges[start] || c > ranges[end]) return -1;mid = start + (end - start) / 2;if(c == ranges[mid]) return results[mid / 2];if(c < ranges[mid]) {if(mid % 2 == 1) {if(c >= ranges[mid - 1]) return results[mid / 2];else end = mid - 2;}else end = mid - 1;}else {if(mid % 2 == 0) {if(c <= ranges[mid + 1]) return results[mid / 2];else start = mid + 2;}else start = mid + 1;}}return -1; // not found. }int get_next3(int *ranges, int *results, int size, int c) {for(int i = 0; i < size;) {if(i % 2 == 0) {if(c >= ranges[i] && c <= ranges[i + 1]) return results[i / 2];else if(c < ranges[i]) return -1;else i += 2;}} }int main() {struct timeval t_begin, t_end;range_map *rm = new range_map();rm->insert(pair<range*, int>(new range(1, 2), 20));rm->insert(pair<range*, int>(new range(3, 37), 27));rm->insert(pair<range*, int>(new range(48, 57), 28));rm->insert(pair<range*, int>(new range(58, 63), 27));rm->insert(pair<range*, int>(new range(97, 128), 122));rm->insert(pair<range*, int>(new range(129, 149), 12));rm->insert(pair<range*, int>(new range(150, 189), 13));rm->insert(pair<range*, int>(new range(200, 245), 14));rm->insert(pair<range*, int>(new range(246, 256), 129));rm->insert(pair<range*, int>(new range(479, 560), 12));int ranges[] = {1, 2, 3, 37, 48, 57, 58, 63, 97, 128, 129, 149, 150, 189, 200, 245, 246, 256, 479, 560};int results[] = {20, 27, 28, 27, 122, 12, 13, 14, 129, 12};// int r = get_next2(ranges, results, 20, 65);// cout << r << endl; gettimeofday(&t_begin,NULL);int result[256];for(int c = 0; c < 256; c++)result[c] = get_next1(rm, c);gettimeofday(&t_end,NULL);double timeuse=1000000*(t_end.tv_sec-t_begin.tv_sec)+(t_end.tv_usec-t_begin.tv_usec);timeuse/=1000000;printf("\nget_next1 time use: %.12f\n", timeuse);// for(int c = 0; c < 256; c++)// cout << result[c] << " ";// cout << endl; gettimeofday(&t_begin,NULL);for(int c = 0; c < 256; c++)result[c] = get_next2(ranges, results, 20, c);gettimeofday(&t_end,NULL);timeuse=1000000*(t_end.tv_sec-t_begin.tv_sec)+(t_end.tv_usec-t_begin.tv_usec);timeuse/=1000000;printf("\nget_next2 time use: %.12f\n", timeuse);// for(int c = 0; c < 256; c++)// cout << result[c] << " ";// cout << endl; gettimeofday(&t_begin,NULL);for(int c = 0; c < 256; c++)result[c] = get_next3(ranges, results, 20, c);gettimeofday(&t_end,NULL);timeuse=1000000*(t_end.tv_sec-t_begin.tv_sec)+(t_end.tv_usec-t_begin.tv_usec);timeuse/=1000000;printf("\nget_next3 time use: %.12f\n", timeuse);// for(int c = 0; c < 256; c++)// cout << result[c] << " ";// cout << endl;return 0; }
复制代码

执行结果为:

get_next1 time use: 0.000302000000
get_next2 time use: 0.000043000000
get_next3 time use: 0.000165000000

说明二分查找算法还是挺高效的。顺序查找也不错,有时候表现的与二分查找差点儿相同。这里的数据比較少,体现不出准确的对照。但至少可能说明二分查找算法比简单的顺序查找(map顺序和数组顺序查找)要快不少。

 

上面是自己的一点拙见,相信二分查找算法肯定不是最高效的算法,但眼下实在想不出更好的办法了。

大家虽然提的想法。不试不知道该算法是好的!

版权声明:本文博客原创文章,博客,未经同意,不得转载。

转载于:https://www.cnblogs.com/hrhguanli/p/4668792.html

http://www.jmfq.cn/news/4850461.html

相关文章:

  • 郑州做网站比较好公司/seo智能优化系统
  • 肥城网站建设费用/刷神马关键字排名软件
  • 做美团网站多少钱/网络营销电子版教材
  • 做网站 源代码/友情链接适用网站
  • 潮州营销型网站建设推广/推广赚钱的平台
  • 做电子手环网站需求分析/网站怎么优化搜索
  • 门户网站建设对策及建议/新东方烹饪学校
  • dreamweaver 创建网站/网络营销策划书ppt
  • 燕郊医疗网站建设/链接转二维码
  • 永州做网站公司/seo营销论文
  • 网站维护升级访问中/太原网站开发
  • 做网站要注意哪一点/广告商对接平台
  • 做网站和微信公众号如何招生/免费的黄冈网站有哪些平台
  • 建设网站怎么做/成都短视频代运营
  • 真人录像龙虎网站制作公司/企业推广网
  • 甘肃省人民政府网站首页/seo实战培训教程
  • 北京赛车网站建设/如何用网站模板建站
  • 国家企业信息官网查询/抖音seo是什么
  • 苏州免费网站制作/软文范文大全1000字
  • 比较好的网站开发公司电话/1688关键词排名查询工具
  • 上海企业名录 企业黄页/大连谷歌seo
  • 个人网站可以做音乐下载网/网络推广公司可不可靠
  • 徐州有哪些网站制作公司/seo最新优化技术
  • 如何建设个人独立网站/实时积分榜
  • html5视频网站模板/湖南省人民政府
  • 做一个网站做少多少钱/搜索引擎的优化方法有哪些
  • 婚纱礼服外贸网站/营销网站类型
  • 网站建设费用预算/seo是什么意思seo是什么职位
  • 最近中文字幕视频2019一页/潍坊百度seo公司
  • 深圳企业网站建设制作网络公司/2022网络热词30个