C++ 数据结构算法 学习笔记(33) -查找算法及企业级应用

C++ 数据结构算法 学习笔记(33) -查找算法及企业级应用

数组和索引

日常生活中,我们经常会在电话号码簿中查阅“某人”的电话号码,按姓查询或者按字母排 序查询;在字典中查阅“某个词”的读音和含义等等。在这里,“电话号码簿”和“字典”都可 看作一张查找表,而按“姓”或者“字母”查询则是按索引查询!

在这里插入图片描述

索引把线性表分成若干块,每一块中的元素存储顺序是任意的,但是块与块间必须按关键字 大小按顺序排列。即前一块中的最大关键字值小于后一块中的最小关键字值。 分块以后,为了快速定义块,还需要建立一个索引表,索引表中的一项对应于线性表中的一 块,索引项由键域和链域组成。键域存放相应关键字的键值,链域存放指向本块第一个节点和最 后一个节点的指针,索引表按关键字由小到大的顺序排列!

数组是特殊的块索引(一个块一个元素):

在这里插入图片描述

哈希表是非常经典的块索引!

在这里插入图片描述

分块查找的算法分两步进行,首先确定所查找的节点属于哪一块,即在索引表中查找其所在的块, 然后在块内查找待查询的数据。由于索引表是递增有序的,可采用二分查找,而块内元素是无序 的,只能采用顺序查找。(块内元素较少,则不会对执行速度有太大的影响

二分查找

二分查找法实质上是不断地将有序数据集进行对半分割,并检查每个分区的中间元素。再重 复根据中间数确定目标范围并递归实行对半分割,直到中间数等于待查找的值或是目标数不在搜 索范围之内!

#include <iostream>
#include <string>using namespace std;int int_compare(const void* key1, const void* key2)
{const int* ch1 = (const int*) key1;const int* ch2 = (const int*) key2;return (*ch1 - *ch2);
}int char_compare(const void* key1, const void* key2)
{const char* ch1 = (const char*)key1;const char* ch2 = (const char*)key2;return (*ch1 - *ch2);
}int BinarySearch(void* sorted, int len, int elemSize, void* search, int (*compare)(const void *key1, const void *key2))
{int left = 0; int right = 0;int middle = 0;left = 0;right = len - 1;while (left <= right){int ret = 0;middle = (left + right) / 2;ret = compare(static_cast<char *>(sorted)+(elemSize*middle), search);if (ret ==0){return middle;}else if (ret >0){right = middle - 1;}else{left = middle + 1;}}return -1;
}int main()
{ int arr[] = { 1,3,7,9,11 };int search[] = {0,1,7,2,11,12};for (int i = 0; i < sizeof(search) / sizeof(search[0]); i++){int index = BinarySearch(arr, sizeof(arr) / sizeof(arr[0]),sizeof(int), & search[i], &int_compare);cout << "The result is: " << index << endl;}char arr1[] = { 'a','c','d','f','j' };char search1[] = {'0','a','e','j','z'};cout << endl;cout << "Char searching..." << endl;for (int i = 0; i < sizeof(search1) / sizeof(search1[0]); i++){int index = BinarySearch(arr1, sizeof(arr1) / sizeof(arr1[0]),sizeof(char), & search1[i], &char_compare);cout << "The result is: " << index << endl;}system("pause");return 0;
}

穷举搜索

有20枚硬币,可能包括4种类型:1元、5角、1角和5分。

已知20枚硬币的总价值为10元,求各种硬币的数量。 例如:4、11、5、0就是一种方案。

而8、2、10、0是另一个可能的方案,显然方案并不是 唯一的,请编写程序求出类似这样的不同的方案一共有多少种?

(1)编程思路。 直接对四种类型的硬币的个数进行穷举。其中,1元最多10枚、5角最多20枚、1角最多 20枚、5分最多20枚。

如果以元为单位,则5角、1角、5分会化成浮点型数据,容易计算出错。可以将1 元、5角、1角、5分变成100分、50分、10分和5分,从而全部采用整型数据处理。

#include <iostream>
#include <string>using namespace std;int main()
{int a100 = 0; //one dollar coinint a50 = 0;int a10 = 0;int a5 = 0;int cnt = 0;for (a100 = 0; a100 <= 10; a100++){for (a50 = 0; a50 <=(1000-a100*100)/50; a50++){for (a10 = 0; a10 <= (1000-a100*100-a50*50)/10; a10++){for (a5 = 0; a5 <= (1000 - a100 * 100 - a50 * 50 - a10*10) / 5; a5++){if ((a100 * 100 + a50 * 50 + a10 * 10 + a5 * 5) == 1000 && (a100 + a50 + a10 + a5) == 20){cout << a100 << "," << a50 << "," << a10 << "," << a5 << "," << endl;cnt++;}}}}}cout << "The total method to have the $10 dollar with 20 coin is: " << cnt << endl;system("pause");return 0;
}

穷举法(枚举法)的基本思想是:列举出所有可能的情况,逐个判断有哪些是符合问题所要求 的条件,从而得到问题的全部解答。 它利用计算机运算速度快、精确度高的特点,对要解决问题的所有可能情况,一个不漏地进行检 查,从中找出符合要求的答案。

用穷举算法解决问题,通常可以从两个方面进行分析:

(1)问题所涉及的情况:问题所涉及的情况有哪些,情况的种数必须可以确定。把它描述 出来。应用穷举时对问题所涉及的有限种情形必须一一列举,既不能重复,也不能遗漏。重复列 举直接引发增解,影响解的准确性;而列举的遗漏可能导致问题解的遗漏。

(2)答案需要满足的条件:分析出来的这些情况,需要满足什么条件,才成为问题的答案。 把这些条件描述出来。

并行搜索

并发的基本概念

所谓并发是在同一实体上的多个事件同时发生。并发编程是指在在同一台计算机上“同时” 处理多个任务。

在这里插入图片描述

要理解并发编程,我们必须要理解如下一些基本概念: 计算机就像一座工厂,时刻在运行,为人类服务。它的核心是CPU,它承担了所有的计算任 务,就像工厂的一个现场指挥官。

在这里插入图片描述

进程就像工厂里的车间,承担“工厂”里的各项具体的“生产任务”,通常每个进程对应一 个在运行中的执行程序,比如,QQ和微信运行的时候,他们分别是不同的进程。

因为特殊原因,现场指挥官人才短缺,整个工厂只有一个指挥官,一次只能指导一个车间生 产,而所有的车间都必须要有现场指挥官在场才能生产。也就是说,一个车间开工的时候, 其他车间都必须停工。

背后的含义:任一时刻,单个CPU一次只能运行一个进程,此时其他进程处于非运行状态。

在这里插入图片描述

一个车间(进程)可以包括多条生产线,线程就好比车间(进程)里的生产线。所有生产线 (设备和人)都属于同一车间的资源,受车间统一调度和调配,并共享车间所有资源(如空 间或洗手间)。

背后的含义:一个进程可以拥有多个线程,每个线程可以可以独立并行执行,多个线程共 享同一进程的资源,受进程管理。

在这里插入图片描述

理解了以上这些概念后,我们接下来再继续讲解并行搜索的概念: 假设我们要从很大的一个无序的数据集中进行搜索,

假设我们的机器可以一次性容纳这么多 数据。从理论上讲,对于无序数据,如果不考虑排序,已经很难从算法层面优化了。而利用 上面我们提到的并行处理思想,我们可以很轻松地将检索效率提升多倍。具体实现思路如下: 将数据分成N个块,每个块由一个线程来并行搜索。

#include <iostream>
#include <string>
#include <Windows.h>
#include <time.h>using namespace std;#define TEST_SIZE	(1024*1024*200)
#define NUMBER	20typedef struct _search 
{int* data;size_t start;size_t end;size_t count;
}search;//int main1()
//{
//	int* data = NULL;
//	int count = 0;
//
//	data = new int[TEST_SIZE];
//
//	for (int i = 0; i < TEST_SIZE; i++)
//	{
//		data[i] = i;
//	}
//
//	time_t start = 0, end = 0;
//	time(&start);
//
//	for (int j = 0; j < 10; j++)
//	{
//		for (int i = 0; i < TEST_SIZE; i++)
//		{
//			if (data[i] == NUMBER)
//			{
//				count++;
//			}
//		}
//	}
//
//	time(&end);
//	cout << "The time used for the search function is: " << end - start << endl;
//	system("pause");
//	return 0;
//}DWORD WINAPI ThreadProc(void* lpParam)
{search* s = (search*)lpParam;time_t start, end;cout << "The new thread is executing..." << endl;time(&start);for (int j = 0; j < 10; j++){for (size_t i = s->start; i < s->end; i++){if (s->data[i] == NUMBER){s->count++;}}}time(&end);cout << "The required time to searching the data is: " << end - start << endl;return 0;
}int main()
{int* data = NULL;int count = 0;int mid = 0;search s1, s2;data = new int[TEST_SIZE];for (int i = 0; i < TEST_SIZE; i++){data[i] = i;}mid = TEST_SIZE / 2;s1.data = data;s1.start = 0;s1.end = mid;s1.count = 0;s2.data = data;s2.start = mid + 1;s2.end = TEST_SIZE -1;s2.count = 0;DWORD threadID1; //Thread 1 identityHANDLE hThread1; //Thread 1 handleDWORD threadID2; //Thread 2 identityHANDLE hThread2; //Thread 2 handlecout << "Creating the threads..." << endl;hThread1 = CreateThread(NULL, 0, ThreadProc, &s1, 0, &threadID1); //Creating first threadhThread2 = CreateThread(NULL, 0, ThreadProc, &s2, 0, &threadID2); // Creating second threadWaitForSingleObject(hThread1, INFINITE);WaitForSingleObject(hThread2, INFINITE);cout << "The process is waiting the thread to return..." << endl;cout << "The total count for the search value is: " << s1.count + s2.count << endl;system("pause");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/333342.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nginx文件解析漏洞测试

环境条件:ubuntu14,已安装docker,docker pull ubuntu:14.04.5 一、Nginx配置 1、使用docker启动容器&#xff1a; docker run -itd --name ubuntu -p 8088:80 ubuntu:14.04.5 2、进入容器&#xff1a; docker exec -it ubuntu /bin/bash 3、然后使用以下语句安装相关环境…

(四)手把手教你内网穿透,实现外网主机访问内网服务器

背景&#xff1a;书接上回&#xff0c; 服务器的使用-CSDN博客 课题组成员都有自己的账号&#xff0c;且能通过内网访问服务器&#xff0c;进行远程连接了。我们知道内网中的主机可以访问公网的主机&#xff0c;反之不可以访问。那么如果课题组成员在家不在内网区域内&#x…

ai发展会不会带来企业的员工垄断呢

写代码写累了&#xff0c;写点个人不成熟的想法&#xff0c;作为记录 随着gpt-4o发布&#xff0c;可以预计的是&#xff0c;AI逐渐能够通过各种外接设备和传感器和真实世界实时交互。那么未来一个接上摄像头&#xff0c;键盘&#xff0c;音响&#xff0c;可移动身体的的AI还会…

如何注册Claude3?解决Claude3无海外手机号接收验证码的问题以及如何订阅Claude Pro

原文链接&#xff1a;如何注册 Claude3&#xff1f;解决 Claude3 无海外手机号接收验证码的问题以及如何订阅 Claude Pro 前言 Claude3已经出来有一段时间了&#xff0c;大家有没有体验过呢&#xff1f;不过从目前来看&#xff0c;Anthropic公司总共推出了3个模型&#xff1…

Jenkins安装 :AWS EC2 Linux

1 JDK11 install # 用的yum安装 # 压缩包安装&#xff0c;下载的jdk-11.0.22_linux-x64_bin.tar.gz在EC2解压&#xff0c;配置环境变量&#xff0c;运行jenkins的时候会报错$ yum -y list java-11* Available Packages java-11-amazon-corretto-devel.x86_64 …

用队列实现栈 用栈实现队列 设计循环队列

用队列实现栈 思路 栈的特点&#xff1a;后进先出 队列的特点&#xff1a;先进先出 使用两个队列实现栈&#xff1a; 我们可以使用两个队列&#xff0c;一个队列为&#xff1a;空队列&#xff0c;一个队列为&#xff1a;非空队列 当我们要出队列时&#xff1a; 将 size - …

多态

多态的概念 通俗来说&#xff0c;就是多种形态&#xff0c;具体点就是完成某个行为&#xff0c;当不同的对象去完成时会产生出不同的状态 多态的定义及实现 多态构成的条件 1、必须通过基类的指针或者引用调用虚函数 2、子类必须对基类的虚函数进行重写 虚函数 被关键字vi…

内网横向移动小补充 --->PTK

大家别急&#xff0c;我的基于资源的约束性委派攻击还在写&#xff0c;这个东西一时半会讲不清楚&#xff0c;所以我在这里先来补充一点横向移动以前没说好的东西&#xff01;&#xff01;&#xff01; 在更啦&#xff0c;别催啦~~~~ 还记得我之前在内网渗透里面讲过这个PTK&a…

2024.5.22 关于 SpringCloud —— Nacos 配置管理

目录 Nacos 配置统一管理 Nacos 配置热部署 Nacos 多环境配置共享 配置优先级 Nacos 配置统一管理 实例理解 我们想要利用 Nacos 在 user-service 的 application.yml 配置文件中新增配置项此处我们将新增配置日期格式为 yyyy-MM-dd HH:mm:ss下图为新增 Nacos 配置统一管理…

基于STM32实现智能园艺系统

目录 引言环境准备智能园艺系统基础代码示例&#xff1a;实现智能园艺系统 土壤湿度传感器数据读取水泵控制温湿度传感器数据读取显示系统用户输入和设置应用场景&#xff1a;智能农业与家庭园艺问题解决方案与优化收尾与总结 1. 引言 本教程将详细介绍如何在STM32嵌入式系统…

基于Zynq 7000 SoC的迁移设计

基于Zynq 7000 SoC的迁移设计 Vivado IDE工具使用IP集成器进行嵌入式开发。各种IP Vivado IDE IP目录中提供&#xff0c;以适应复杂的设计。您也可以添加 自定义IP到IP目录。 您可以将基于Zynq 7000平台处理器的设计迁移到Vivado design Suite中 使用以下步骤。 1.生成系统基础…

【搜索方法推荐】高效信息检索方法和实用网站推荐

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

亚马逊云主管马特·加尔曼面临压力,致力于在人工智能领域赶超竞争对手

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

四川景源畅信:抖音小店新手如何做?

随着短视频平台的兴起&#xff0c;抖音小店成为了许多创业者的新选择。但是&#xff0c;对于新手来说&#xff0c;如何在抖音上开设并经营好自己的小店呢?本文将围绕这一问题展开讨论。 一、明确目标和定位作为抖音小店的新手&#xff0c;首先要明确自己的经营目标和定位。是想…

【CTF Web】CTFShow web4 Writeup(SQL注入+PHP+字符型注入)

web4 1 管理员阿呆又失败了&#xff0c;这次一定要堵住漏洞 解法 注意到&#xff1a; <!-- flag in id 1000 -->拦截很多种字符&#xff0c;连 select 也不给用了。 if(preg_match("/or|\-|\\\|\/|\\*|\<|\>|\!|x|hex|\(|\)|\|select/i",$id)){die(&q…

Pycharm最新安装教程(最新更新时间2024年5月27日)

ps&#xff1a;本教程Pycharm安装&#xff0c;最新更新时间&#xff1a;2024年5月27日&#xff0c;公众号持续更新关注公众号防失联哦 Pycharm 再次更新了一个小版本。又回到老话题&#xff0c;2023.3.2这个版本是否还能安装&#xff0c;笔者也亲测了一下。还是沿用本站之前的…

刷题之从前序遍历与中序遍历序列构造二叉树(leetcode)

从前序遍历与中序遍历序列构造二叉树 前序遍历&#xff1a;中左右 中序遍历&#xff1a;左中右 前序遍历的第一个数必定为根节点&#xff0c;再到中序遍历中找到该数&#xff0c;数的左边是左子树&#xff0c;右边是右子树&#xff0c;进行递归即可。 #include<vector>…

零基础PHP入门(一)选择IDE和配置环境

配置环境 官网下载安装包&#xff0c;windows https://windows.php.net/download#php-8.3 我是下载的最新版&#xff0c;也可以切换其他版本 https://windows.php.net/downloads/releases/archives/ 下载好压缩文件后&#xff0c;双击解压到一个目录 D:\soft\php 复制ph…

技术贴 | Query 物理计划构建指南

在往期博客《执行器 - Query 执行详解》中&#xff0c;我们介绍到到一条 Query 的 SQL 语句需要经过&#xff1a;词法分析 —— 生成 AST 语法树 —— 生成物理计划。本期博客我们接续上篇讲解一条 Query 语句物理计划的具体结构&#xff0c;以及如何构建物理计划。 物理计划是…

无人机技术:倾转旋翼飞行器的关键技术详解

一、总体设计 倾转旋翼飞行器作为一种独特的垂直起降与水平巡航的航空器&#xff0c;其总体设计是关键技术之一。总体设计涵盖了飞行器的整体布局、重量分配、气动性能、机械结构设计等多个方面。在总体设计中&#xff0c;需要充分考虑飞行器的垂直起降、悬停、过渡飞行和水平…