【数据结构与算法分析】介绍蛮力法以及相关程序案例

news2024/11/19 3:47:32

文章目录

  • 蛮力法之排序
    • 选择排序
    • 冒泡排序
    • 实际应用
  • 蛮力法之最近对和凸包问题
    • 最近对问题
    • 凸包问题

    蛮力法(brute force),其本质跟咱常说的暴力法是一样的,都是一种简单直接地解决问题的方法,通常直接基于问题的描述和所涉及的概念定义进行求解。

蛮力法之排序

选择排序

  选择排序,其本质是将位置与对应的数据大小相匹配,比如:在遍历整个列表时,先找到最小(大)的元素,将其与第一个元素交换;再从第二个元素开始遍历,找到第二小(大)的元素,将其与第二个元素交换;再从第n-1个元素开始遍历,找到第n-1小(大)的元素,将其与第n-1个元素交换。在遍历列表n-1次后,列表就按指定顺序排列完成。此时:
A   1   ⩽ A   2   ⩽ A   3   ⩽ … … ⩽ A   n − 1   ⩽ A n A~1~\leqslant A~2~\leqslant A~3~\leqslant ……\leqslant A~n-1~\leqslant An A 1 A 2 A 3 ……A n1 An
  其实现代码为:

void selectSort(int*a,int len)
{
	for(int i=0;i<len;++i)
	{
		for(int j=i+1;j<len;++j)
		{
			if(a[i]>a[j])
			{
				int temp = a[i];
				a[i] = a[j];
				a[j] = temp;
			}
		}
	}		
}

案例分析
  如果我们使用选择排序对列表 0,2,4,1,9,6,3,8,5,7进行排序,那么其排序过程将会是:
在这里插入图片描述
  使用DEV跑得到结果:
在这里插入图片描述
  其时间复杂度为O(n2),空间复杂度为0(n)
)

冒泡排序

  冒泡排序,其本质是比较相邻两个元素大小,即,如果 an-1< an ,那么就交换两者位置, 而选择排序是选择相应的元素放置到合适的位置。
  其实现代码为:

void bubbleSort(int*a,int len)
{
	for(int i=0;i<len-1;++i)
	{
		for(int j=0;j<len-1-i;++j)
		{
			if(a[j]>a[j+1])
			{
				int temp = a[j+1];
				a[j+1] = a[j];
				a[j] = temp;
			}
		}
	}		
}

案例分析
  如果我们使用冒泡排序对列表 0,2,4,1,9,6,3,8,5,7进行排序,那么其排序过程将会是:

在这里插入图片描述
  使用DEV跑得到结果:
在这里插入图片描述
  与选择排序一样,其时间复杂度为O(n2),空间复杂度为0(n)

实际应用

问题:应用选择排序将序列E,X,A, M,P,L,E按照字母顺序排序

程序解答
  直接将上述的选择排序排序内容从整数变成字符即可,一样的逻辑。

#include <iostream>
using namespace std;

void outPut(char *a,int len)
{
	for(int i=0;i<len;i++)
		cout<<a[i]<<" ";
	cout<<endl;
}

void selectSort(char*a,int len)
{
	for(int i=0;i<len-1;++i)
	{
		for(int j=i+1;j<len;++j)
		{
			if(a[i]>a[j])
			{
				char temp = a[i];
				a[i] = a[j];
				a[j] = temp;
			}
		}
	}		
}

int main(void)
{
	char a[] = {'E','X','A','M','P','L','E'};
	
	cout<<"排序前:";
	outPut(a,7);
	selectSort(a,7);
	cout<<"排序后:";
	outPut(a,7);
	
	return 0;
}

蛮力法之最近对和凸包问题

最近对问题

最近对问题描述

  最近点对问题要求:在一个包含n个点的集合中,找出距离最近的两个点。这种处理平面或者高维空间的邻近点的问题,在各种计算几何问题当中是最简单的。问题中的点可以代表飞机、邮局这类实体对象,也可以代表数据库记录、统计样本或者 DNA序列等非实体对象。航空交通控制人员可能会对两架最可能发生碰撞的飞机感兴趣。区域邮政管理者可能需要依赖最近对问题的解来寻找地理位置最近的邮局。

解答
  使用蛮力法解决最近对问题,一般是采用先将任意两点之间的距离求出,再找到这些距离中的最小值

例如:

题目
  在集合{16,4,23,6,5,94,77}中打印出两数差值最小的两个数;

解析:
  由上述最近对问题核心:求两两数值的最小差值,不难有下图中的求解过程:
在这里插入图片描述
  根据上述的模拟过程,可写出下述程序:

#include <iostream>
#include <math.h>
using namespace std;

void findMinValue(int*a,int len)
{
	int minValue,dp[2];
	// 遍历数组 求任意两数之差 
	for(int i=0;i<len-1;i++)
	{
		for(int j=i+1;j<len;j++)
		{
			int temp = abs(a[i]-a[j]);
			// 比较是否是最小的差 
			if((i==0&&j==1) || temp < minValue)
			{
				dp[0] = a[i];
				dp[1] = a[j];
				minValue = temp;
			}
		}	
	}	
	cout<<"差值最小的两数为:"<<dp[0]<<" "<<dp[1]<<endl; 
} 

int main(void)
{
	int a[] = {16,4,23,61,5,94,77};
	findMinValue(a,7);
	
	return 0;
}

  使用DEV运行求解有:
在这里插入图片描述

  与选择排序类似,该程序的时间复杂度为O(n2),空间复杂度为O(n)。

凸包问题

  设p,=(x1, y1), p2=(x2,y2). …, pn=(xn,yn)是平面上n个点构成的集合S,包含集合S中所有点的最小多边形就称为凸包多边形,也就是将最外围所有点连接起来构成的多变形,将其称为凸包多边形。 下图就是一个包含点集的凸包多边形。
在这里插入图片描述

例如:
  求出二维平面中点 (1,1),(2,1)、(4,1)、(2,2)、(3,2)、(4,2)、(2,3)、(4,3)、(5,3)、(3,4) 所构成的最小凸包。
  人为画出凸包多边形有:
在这里插入图片描述

分析:
  凸包多边形,是由点集最外层点所构成,再结合上图,是不是可以看出当凸边多边形边确定时,其他点都在边的一侧从数学角度上来说,也就是当凸边多边形边确定时,任意一点到这条边的距离的符号相同(即同为正数,或同为负数,或者为0)
  然后,在将任意两点连接构成一条直线,再判断这条直线是否符合上述凸边多边形边的性质,如果符合该性质就这两点加入到结果集中;否则就继续找其他的直线。
  当以点(1,1)为凸包多边形边的一点时,将该点依次连接其他任意点,例如:连接点(2,1),通过点到直线的距离公式,可以算出任意点到该直线都为正数,因此,可以作为凸多边形的一边;而连接点(5,3)时,由于点散落在直线两侧,使用距离公式,可以算出部分点到直线距离为正数,而剩余点到直线的距离为负数,因此,该边不可作为凸多边形的一边。
在这里插入图片描述
  根据上述的分析,可以写出下述程序:

#include<iostream>
#include<cmath>
#include<vector>
#include<map>
using namespace std;

int check(vector<pair<float, float> >&data,pair<float, float>&target)
{
	// 判断数组data中是否已经包含该数值  包含就返回1 否则返回0 
	for(int i=0;i<data.size();i++)
		if(data[i].first==target.first && data[i].second==target.second)
			return 1;
	
	return 0;
}
 
vector<pair<float, float> > convexHull(vector<pair<float,float> > &point){
	// 集合点少于2时 可以直接返回 
	if(point.size() <= 2)  
 	return	point;
 	
	vector<pair<float, float> > pointPairVec;
	//两个循环扫描每个点
	for(int i=0; i<point.size()-1; i++){
		for(int j=i+1; j<point.size(); j++){
			// 求一个一次函数的直线A:ax+by=c (a=y2-y1,b=x2-x1,c=x1y2-y1x2)
			float a = point[j].second - point[i].second;   
			float b = point[i].first - point[j].first;
			float c = point[i].first*point[j].second - point[i].second*point[j].first;
			//记录直线两边的点
			int sign1 = 0, sign2 = 0;  
			//扫描直线A外的所有的点
			for(int k=0; k<point.size(); k++){
				if(k==i || k==j)
					continue;
				else{
					// 求点到直线A的距离 
					float sign = a*point[k].first + b*point[k].second - c;
					// 该点在直线上边 
					if(sign > 0)
						sign1++;
					// 该点在直线下边
					else if(sign < 0)
						sign2++;					
				} 	 
			}
			// 该点不符合要求 继续查找 
			if(sign1 > 0 && sign2 > 0)
				continue;
			// 将符合要求的两点加入结果集 
			else{
				// 将不重复的值加入到结果集 
				if(!check(pointPairVec,point[i]))
					pointPairVec.push_back(point[i]);
				if(!check(pointPairVec,point[j]))	
					pointPairVec.push_back(point[j]);
			}	
		}
	}

	return pointPairVec;
}
 
int main(){
	// 保存数据集
	vector<pair<float, float> > pointsArray(10);
	
	// 生成数据集	
	pointsArray[0] = pair<float, float>(1,1); 
	pointsArray[1] = pair<float, float>(2,1);
	pointsArray[2] = pair<float, float>(4,1);
	pointsArray[3] = pair<float, float>(2,2);
	pointsArray[4] = pair<float, float>(3,2);
	pointsArray[5] = pair<float, float>(4,2);
	pointsArray[6] = pair<float, float>(4,3);
	pointsArray[7] = pair<float, float>(2,3);
	pointsArray[8] = pair<float, float>(5,3);
	pointsArray[9] = pair<float, float>(3,4);
	
	cout<<"源数据:"<<endl; 
	for(int i=0; i<pointsArray.size(); i++)
		cout<<"("<<pointsArray[i].first<<","<<pointsArray[i].second<<")"<<" ";
	
	vector<pair<float, float> > convex = convexHull(pointsArray);
	cout<<endl<<"求出能够构成凸包的点:"<<endl;
	for(int i=0; i<convex.size(); i++)
		cout<<"("<<convex[i].first<<","<<convex[i].second<<")"<<" ";

	return 0;
} 

  DEV跑出结果为:
在这里插入图片描述


  小编主学嵌入式,算法能力一般,欢迎大家查看小编其他文章,同时也欢迎大家留言或私信交流哈!

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

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

相关文章

【嵌入式】HC32F460串口接收超时中断+DMA

一 项目背景 项目需要使用一款UART串口编码器&#xff0c;编码器的数据以波特率57600持续向外发送。但这组数据包没有固定的包头和校验尾&#xff0c;仅仅是由多圈圈数和单圈角度组成的六字节数据码&#xff0c;这样接收到的数组无法确定实际的下标&#xff0c;所以这边考虑用串…

8月起,《PMBOK®指南(第七版)》将被采用,考PMP的注意了!

PMP第七版教材采用时间定了&#xff01;&#xff01;&#xff01;2023年【8月开始】第一次使用第七版教材&#xff0c;通知明显指出&#xff0c;第六版的关键知识任然还是有效的。第七版做的调整还是蛮大的&#xff0c;首次提出了项目管理的 12 项原则和8个项目绩效域&#xff…

Java基础语法小结来啦

简单的来说&#xff0c;一个java的程序他是有一系列对象的集合组成&#xff0c;通过对这些对象相互间调用的方式协同工作&#xff0c;下面就是我有关于Java基础语法的一些小结。 一、return简单使用 下面来一个Java程序&#xff0c;表示的是在self1这个包中我们创建了一个名叫…

Skywalking ui页面功能介绍

菜单栏 仪表盘&#xff1a;查看被监控服务的运行状态&#xff1b; 拓扑图&#xff1a;以拓扑图的方式展现服务之间的关系&#xff0c;并以此为入口查看相关信息&#xff1b; 追踪&#xff1a;以接口列表的方式展现&#xff0c;追踪接口内部调用过程&#xff1b; 性能剖析&am…

GEE学习笔记 八十:批量下载影像

最近问如何批量导出集合的小伙伴非常多&#xff0c;一个一个回复太麻烦&#xff0c;我这里直接给一段例子代码吧&#xff1a; var l8 ee.ImageCollection("LANDSAT/LC08/C01/T1_SR"); var roi /* color: #d63000 */ee.Geometry.Polygon( [[[115.64960937…

从0到1一步一步玩转openEuler--17 openEuler DNF(YUM)检查更新

文章目录17.1 检查更新17.2 升级17.3 更新所有的包和它们的依赖DNF是一款Linux软件包管理工具&#xff0c;用于管理RPM软件包。DNF可以查询软件包信息&#xff0c;从指定软件库获取软件包&#xff0c;自动处理依赖关系以安装或卸载软件包&#xff0c;以及更新系统到最新可用版本…

Nacos框架服务注册发现和配置中心原理

文章目录1.简介2.整体架构和原理2.1 服务发现注册原理2.1.1 注册和拉取数据2.1.2 Server集群一致性2.1.3 健康检查2.2 配置中心原理2.2.1 支持功能和资源模型2.2.2 server集群数据一致性问题2.2.3 client和server的通信监听改动方式2.2.4 client拉取数据2.2.5 client请求server…

kubernetes教程 --Pod生命周期

Pod生命周期 pod创建过程运行初始化容器&#xff08;init container&#xff09;过程运行主容器&#xff08;main container&#xff09;过程 容器启动后钩子&#xff08;post start&#xff09;、容器终止前钩子&#xff08;pre stop&#xff09;容器的存活性探测&#xff08;…

利用设计模式、反射写代码

软件工程师和码农最大的区别就是平时写代码时习惯问题&#xff0c;码农很喜欢写重复代码而软件工程师会利用各种技巧去干掉重复的冗余代码。 业务同学抱怨业务开发没有技术含量&#xff0c;用不到设计模式、Java 高级特性、OOP&#xff0c;平时写代码都在堆 CRUD&#xff0c;个…

网站项目部署在k8s案例与Jenkins自动化发布项目(CI/CD)

在K8s平台部署项目流程 在K8s平台部署Java网站项目 制作镜像流程 第一步&#xff1a;制作镜像 使用镜像仓库&#xff08;私有仓库、公共仓库&#xff09;&#xff1a; 1、配置可信任&#xff08;如果仓库是HTTPS访问不用配置&#xff09; # vi /etc/docker/daemon.json { "…

matlab 简单的水轮机系统的模糊pid控制仿真

1、内容简介略641-可以交流、咨询、答疑2、内容说明模糊介绍&#xff1a;Matlab4.2以后的版本中推出的模糊工具箱(Fuzzy Toolbox)&#xff0c;为仿真模糊控制系统提供了很大的方便。 在Simulink环境下对PID控制系统进行建模是非常方便的&#xff0c;而模糊控制系统与PID控制系统…

DataFrame 循环处理效率的记录

几种工具的处理效率比较&#xff1a; 每次循环都使用复杂的操作尽可能拆分成向量化操作&#xff0c;也可转为numpy&#xff0c;再用numba加速。 对 DataFrame 中的数据做循环处理的效率&#xff1a; 方法一&#xff1a;下标循环 for i in range(len(df)): if df.iloc[i][…

GEE学习笔记 七十七:GEE学习方法简介

这是一篇关于学习方法的思考探索&#xff0c;当然我不会大篇文章介绍什么学习方法&#xff08;因为我也不是这方面的专家?&#xff09;&#xff0c;这个只是总结一下我是如何学习GEE以及在学习中遇到问题时如何解决问题的。我写这篇文章的目的就是在和一些学习GEE的新同学接触…

Stable diffusion扩散模型相关原理

时隔两年半&#xff08;2年4个月&#xff09;&#xff0c;我又回来研究生成技术了。以前学习研究GAN没结果&#xff0c;不管是技术上&#xff0c;还是应用产品上&#xff0c;结果就放弃了&#xff0c;现在基于diffusion的技术又把生成技术带上了一个新的高度。现在自己又来研究…

一款好的低代码开发平台应该是什么样?

一款好的低代码开发平台应该是什么样&#xff1f; 以企业级应用构建来讲&#xff0c;完成一个应用复杂度随着技术的进步、需求的细化、业务要求的变化并不是逐渐降低&#xff0c;而是逐渐提升。用户想要有更好的体验&#xff0c;复杂度更是成倍提升。 基于此&#xff0c;低代码…

【机器学习】Sklearn 集成学习-投票分类器(VoteClassifier)

前言 在【机器学习】集成学习基础概念介绍中有提到过&#xff0c;集成学习的结合策略包括&#xff1a; 平均法、投票法和学习法。sklearn.ensemble库中的包含投票分类器(Voting Classifier) 和投票回归器&#xff08;Voting Regressor)&#xff0c;分别对回归任务和分类任务的…

比Teambition、Worktile 更适合研发团队的几大工具盘点

Worktile 和 Teambitiom 哪个更好&#xff1f;两个产品各有特点。1.Teambition 优势&#xff1a;操作简单、个人版永不收费、更适合小型团队&#xff1b;2.Teambition 劣势&#xff1a;无法满足中大型团队复杂的项目管理、自定义能力弱、无法与钉钉以外的工具打通等&#xff1b…

再次遇到RuntimeError: CUDA error: an illegal memory access was encountered

之前遇到过一次记录下来了&#xff0c;第一次遇到 翻看之前的记录&#xff0c;首先想着如何让pycharm准确地显示错误。 1:os.environ[‘CUDA_LAUNCH_BLOCKING’] 1’,模型前加这句&#xff0c;但是我在train文件中已经加了&#xff0c;还是不清楚报错原因。 2&#xff1a;使用…

Python快速上手系列--三元表达式--入门篇

不知道你是否在写代码的时候会用到很多的if else的判断呢。如果是&#xff0c;不妨看完这一篇文章&#xff0c;看看是否对你有一定的帮助。先来看看三元表达式的写法&#xff1a;那么怎么写呢&#xff0c;看看&#xff1a;这里的意思是&#xff0c;如果为真&#xff0c;则输入1…

RTX40 系列游戏本与台式机显卡 AI 计算力对比

RTX40 系列游戏本还有几天就上市了&#xff0c;商家选了个比较特别的日子&#xff0c;2 月 22 号 22:00&#xff0c;真是有心了。为了用游戏本做 AI 的朋友选的时候有的放矢&#xff0c;特意查了一下 RTX40 系列的 CUDA 核心与频率&#xff0c;计算一下 FP32 TFLOPS&#xff0c…