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.mzph.cn/news/842543.shtml

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

相关文章

【FPGA】Verilog:2-bit 二进制比较器的实现(2-bit binary comparator)

解释 2-bit 二进制比较器仿真结果及过程说明(包括真值表和卡诺图) 真值表和卡洛图如下: 2-bit Binary Comparator A1 A2 B1

写好的文章怎样联系媒体投稿?

作为单位信息宣传的桥梁,我肩负着将单位的每一次活动、每一项成就转化为社会认可与赞美的重任。初涉此职,我满腔热血,以为凭借扎实的文字功底与不懈的努力,便能在各大媒体平台上为单位赢得一席之地。然而,现实很快就给了我一记响亮的耳光。 我最初采取的是最直接的方式——邮箱…

QT 使用QLsitView 实现多个子项选中取消效果

文章目录 效果图概述部分代码总结 效果图 概述 整个界面的布局介绍请看这篇博客想要的到这种自由选择中的Item效果&#xff0c;需要使用到Model-view的思想&#xff0c;每个item中都要存放一个标志位&#xff0c;用在Paint函数去判断是否绘制为按下的状态。每次item被点击时&a…

记录下所遇到远程桌面连接方法winSCP跟mstsc

之前公司使用过连接远程桌面&#xff0c;今天又遇到要使用远程桌面问题&#xff0c;来记录下。 之前公司使用的是winR 然后回车弹出 后面按照用户名密码就能登陆了 今天后台给了我一张图片准备接着用这个方法&#xff0c;后台就说这个东西要下载winSCP 后台发给我图片 然后去…

[笔试强训day09]

文章目录 BC146 添加逗号DP2 跳台阶JZ61 扑克牌顺子解法一&#xff1a;排序模拟解法二&#xff1a;规律哈希 BC146 添加逗号 BC146 添加逗号 #include<iostream> #include<string>using namespace std;int main() {string s;cin>>s;string ans;for(int i0;i…

LLaMa系列模型详解(原理介绍、代码解读):LLaMA 2

LLaMA 2 大型语言模型&#xff08;LLMs&#xff09;作为高度能力的人工智能助手&#xff0c;在需要跨多个领域专家知识的复杂推理任务中表现出巨大潜力&#xff0c;包括编程和创意写作等专业领域。它们通过直观的聊天界面与人类互动&#xff0c;这导致了快速和广泛的公众采用。…

军工单位如何做到安全跨网文件交换与导出的

在现代信息化战争中&#xff0c;军工单位在信息安全方面的需求尤为突出。跨网文件交换与导出作为军工单位日常运营的重要环节&#xff0c;面临着网络带宽限制、数据安全风险、合规性要求和传输稳定性等挑战。下面&#xff0c;我们将从以下几个方面探讨军工单位如何实现安全、高…

【C++】开源:RabbitMQ安装与配置使用(SimpleAmqpClient)

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不迷路&#x1…

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

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

多线程JUC 第2季 BlockingQueue 阻塞队列

一 阻塞队列 1.1 阻塞队列介绍 阻塞队列&#xff08;BlockingQueue&#xff09;是一个在队列基础上又支持了两个附加操作的队列&#xff1a; put方法&#xff1a;当队列装满时&#xff0c;添加的线程则被阻塞&#xff0c;直到队列不满&#xff0c;则可用。 take方法&#x…

力扣2028. 找出缺失的观测数据

题目&#xff1a; 现有一份 n m 次投掷单个 六面 骰子的观测数据&#xff0c;骰子的每个面从 1 到 6 编号。观测数据中缺失了 n 份&#xff0c;你手上只拿到剩余 m 次投掷的数据。幸好你有之前计算过的这 n m 次投掷数据的 平均值 。 给你一个长度为 m 的整数数组 rolls &a…

【Linux 网络】网络基础(三)(数据链路层协议:以太网协议、ARP 协议)

一、以太网 两个不同局域网的主机传递数据并不是直接传递的&#xff0c;而是通过路由器 “一跳一跳” 的传递过去。 跨网络传输的本质&#xff1a;由无数个局域网&#xff08;子网&#xff09;转发的结果。 所以&#xff0c;要理解数据跨网络转发原理就要先理解一个局域网中数…

安全厂商第一站!OASA 走进绿盟科技圆满结束

近日&#xff0c;龙蜥社区安全联盟&#xff08;OASA&#xff09;走进联盟成员单位绿盟科技集团股份有限公司&#xff08;以下简称“绿盟科技”&#xff09;&#xff0c;就未来合作方向&#xff0c;双方进行了一次深入的合作交流。该会议共有 11 位人员出席&#xff0c;有来自绿…

视频监控平台AS-V1000产品介绍:账户或用户数据的导入和导出功能介绍

目录 一、功能描述 &#xff08;一&#xff09;导入功能定义 &#xff08;二&#xff09;导出功能定义 二、用户数据的导入导出的作用 三、AS-V1000新版本的导出和导入功能介绍 &#xff08;一&#xff09;功能主界面 &#xff08;二&#xff09;导出功能 1、导出操作 …

从零开始构建 Vision Transformer(ViT) 模型

Transformer 模型最早由 Vaswani 等人在 2017 年论文 Attention Is All You Need 中提出&#xff0c;并已广泛应用于自然语言处理。 2021年&#xff0c;Dosovitsky 等人在论文An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale中提出将 Transforme…

第十二届蓝桥杯物联网试题(国赛)

不得不说国赛相比较省赛而言确实&#xff0c;功能变得更加复杂&#xff0c;更加繁琐&#xff0c;特别是串口LORA通信相结合的更加频繁&#xff0c;且对收取的字符处理要求要更加复杂&#xff0c;处理判别起来会更加复杂。 对于收发数据本身来说&#xff0c;收发的数据本身是以…

每日一题——Python实现PAT甲级1029 Median(举一反三+思想解读+逐步优化)

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的方法 代码功能和结构点评 时间复杂度分析 空间复杂度分析 优化建议 我要更强…

深度学习环境安装教程-anaconda-python-pytorch

首先是anaconda的安装&#xff0c;可以从下面地址下载安装包 Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 尽量选择最新的日期的anaconda进行安装&#xff0c;我这里是windows电脑&#xff0c;因此选择了windos-x86_64.exe&#xf…

如何在anaconda的环境下安装langchain

1、安装anaconda&#xff1b; 2、在终端上&#xff0c;输入&#xff1a; conda install langchain -c conda-forge Proceed ([y]/n)? y 输入&#xff1a;Y 3、安装完成后&#xff0c;输入&#xff1a; python -c "import langchain; print(langchain.__version__)&…

Redisson集成SpringBoot

前言&#xff1a;Redisson集成SpringBoot主要有两种方式&#xff0c;一个是使用redisson-spring-boot-starter依赖&#xff08;优先推荐&#xff09;&#xff0c;毕竟springboot主打的就是约定大于配置&#xff0c;这个依赖就是为springboot准备的。 再一种方式就是引入rediss…