算法设计与分析实验报告python实现(串匹配问题、采用分治法求解最大连续子序列和问题、用分治策略求众数问题、最近点对问题)

一、 实验目的

1.加深学生对算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;
2.提高学生利用课堂所学知识解决实际问题的能力;
3.提高学生综合应用所学知识解决实际问题的能力。

二、实验任务

1、串匹配问题
给定一段文本,在该文本中查找并定位任意给定字符串。
要求:
(1)实现BF算法;
(2) 实现BF算法的改进算法:KMP算法
2、采用分治法求解最大连续子序列和问题
给定一个有n(n≥1)个整数的序列,要求求出其中最大连续子序列的和。
例如: 序列(-2,11,-4,13,-5,-2)的最大子序列和为20序列(-6,2,4,-7,5,3,2,-1,6,-9,10,-2)的最大子序列和为16。
3、用分治策略求众数问题
问题描述:给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数。多重集S中重数最大的元素称为众数。要求对给定的又n个自然数的组成的多重集S,计算S的众数及其重数。
4、最近点对问题
设p1=(x1, y1), p2=(x2, y2), …, pn=(xn, yn)是平面上n个点构成的集合S,设计算法找出集合S中距离最近的点对。
(1)分别用蛮力法和分治法求解最近对问题;
(2)分析算法的时间性能,设计实验程序验证分析结论。

三、实验设备及编程开发工具

实验设备:Win10电脑
开发工具:Python 3.7,Pycharm

四、实验过程设计(算法思路及描述,代码设计)

1、串匹配问题

给定一段文本,在该文本中查找并定位任意给定字符串。
要求:
(1)实现BF算法;
(2)实现BF算法的改进算法:KMP算法

(1)解题思路:
BF算法就是暴力求解,用所求字符串s2与主串s1做匹配,当不匹配时,从本次主串循环的下一个字符开始重新匹配。

代码:

def BF_algorithm(s1,s2): n1 = len(s1) n2 = len(s2)i,j = 0,0while i < n1 and j < n2:if (s1[i] == s2[j]):i += 1j += 1else:i = i - j + 1j = 0if j >= n2:return i - n2else:return -1

(2)解题思路:

KMP算法需要一个next数组,next数组的含义就是一个固定字符串的最长前缀和最长后缀相同的长度。当匹配失败时,数组下标会移动到最长前缀的后一个位置,从而减少了重复匹配。

代码:

def get_next(p):i, k, m = 0, -1, len(p)p_next = [-1] * mwhile i < m-1:if k == -1 or p[i] == p[k]:i, k = i+1, k+1if p[i] == p[k]:p_next[i] = p_next[k]else:p_next[i] = kelse:k = p_next[k]return p_nextdef KMP_algorithm(t,p):j, i = 0, 0n, m = len(t), len(p)p_next = get_next(p)while j < n and i < m:if i == -1 or t[j] == p[i]:j, i = j+1, i+1else:i = p_next[i]if i == m:return j-ireturn -1# 测试
t = "abbcabcaabbcaa"  # 目标串
p = "abbcaa"  # 模式串
print(KMP_algorithm(t, p))

2、采用分治法求解最大连续子序列和问题

给定一个有n(n≥1)个整数的序列,要求求出其中最大连续子序列的和。
例如: 序列(-2,11,-4,13,-5,-2)的最大子序列和为20序列(-6,2,4,-7,5,3,2,-1,6,-9,10,-2)的最大子序列和为16。

解题思路:
分治法求最大连续子序列问题,可以先从序列的中间分开,分别求左序列和右序列的最大连续子序列,但是还需要考虑如果最大连续子序列正好越过序列的划分线的情况。如果最大连续子序列刚好越过划分线,那么它必然是左边最大连续子序列和右边连续最大子序列的和。所以我们只需要比较左边最大连续子序列,右边最大连续子序列,左边最大连续子序列加上右边最大连续子序列的和,从这三者中取最大值就可以求出整个序列的最大连续子序列。

代码:

def Max_zixulie(nums):n = len(nums)if n == 1:return nums[0]else:max_left = Max_zixulie(nums[0:n//2])max_right = Max_zixulie(nums[n//2:n])temp,max_leftsum = 0,0for i in range(n//2 - 1,-1,-1):temp = temp + nums[i]max_leftsum = max(temp,max_leftsum)temp,max_rightsum = 0,0for i in range(n//2,n):temp = temp + nums[i]max_rightsum = max(temp,max_rightsum)return max(max_left,max_right,max_leftsum + max_rightsum)print(Max_zixulie([-2,11,-4,13,-5,-2]))

3、用分治策略求众数问题

问题描述:给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数。多重集S中重数最大的元素称为众数。要求对给定的又n个自然数的组成的多重集S,计算S的众数及其重数。

解题思路:
首先需要用分治策略解题,所以需要对元素进行排序,然后选取序列中间的元素,由它出发向前和向后寻找和它一样的元素,从而记录众数和重数。接下来从左侧和右侧分别继续递归比较,并在比较过程中判断是否大于已知的重数。在递归比较规程中,我们需要用众数比较剩下的左右剩余序列长度,如果众数大于等于左/右剩余序列长度,那么就不需要进行比较,直接输出就可以。

代码:

p, q = 0, 0
def ZhongShu(nums):n = len(nums)global p,qz_max,k_max,left,right = split(nums)if k_max > q:q = k_maxp = z_maxif left > q:ZhongShu(nums[0:left])if n - right > q:ZhongShu(nums[right:n])return p,qdef split(nums):n = len(nums)low, high = 0, n//2 + 1while low < n:if nums[low] == nums[n//2]:breakelse:low += 1while high < n:if nums[high] == nums[n//2]:high += 1else:breakz = nums[low]k = high - lowreturn z,k,low,highprint(ZhongShu([1,1,1,1,1,1,2,3,3,4,4,5,5,5,6,6,6,8,8,8,8,8,8,8]))

4、最近点对问题

设p1=(x1, y1), p2=(x2, y2), …, pn=(xn, yn)是平面上n个点构成的集合S,设计算法找出集合S中距离最近的点对。
(1)分别用蛮力法和分治法求解最近对问题;
(2) 分析算法的时间性能,设计实验程序验证分析结论。

(1)解题思路:
蛮力法直接用for循环遍历,对每两个点都做运算,并且比较记录最小值,最后输出最短距离和最近的点对。
分治方法在考虑了左、右两边各自的最近点对之后,还需要考虑是否会有最近的点对穿过了我们的划分线。这其实和寻找最长连续子序列有异曲同工之处,但是在考虑这个问题上,我们只需要从划分线向两侧分别延展已求的最近点对长度就可以,然后寻找在这个区域内的最近点对。

代码:(蛮力法)

def ManLi(nums):n = len(nums)x = float('inf')if n <= 1:return Falsefor i in range(1,n):j = 1while j <= i:y = pow((nums[i][0] - nums[i - j][0]) ** 2 + (nums[i][1] - nums[i - j][1]) ** 2,0.5)x = min(x,y)if x == y:l = []l.append(nums[i])l.append(nums[i - j])j += 1return x,l[0],l[1]print(ManLi([[0,4],[1,1],[1,5],[2,4],[3,2],[3,5],[4,0],[4,3],[5,2],[5,5]]))

代码:(分治法)

import sys
import mathdef distance(x, y):return math.sqrt((x[0] - y[0]) ** 2 + (x[1] - y[1])** 2)def FenZhi(points):n = len(points)if n < 2:return sys.maxsize, None, Noneelif n == 2:return distance(points[0], points[1]), points[0], points[1]points = sorted(points)half = (n - 1) // 2d1, a1, b1 = FenZhi(points[:half])d2, a2, b2 = FenZhi(points[half:])d, a, b = (d1, a1, b1) if d1 < d2 else (d2, a2, b2)calibration = points[half][0]left, right = [], []for u in points:if calibration - d < u[0] < calibration:left.append(u)elif calibration <= u[0] < calibration + d:right.append(u)right = sorted(right, key=lambda x: (x[1], x[0]))res = dfor u in left:l, r = -1, len(right) - 1while r - l > 1:m = (l + r) >> 1if right[m][1] <= u[1] - d:l = melse:r = midx = rfor j in range(7):if j + idx >= len(right):breakif distance(u, right[idx + j]) < res:res = distance(u, right[idx + j])a, b = u, right[idx + j]return res, a, bprint(FenZhi([[0,4],[1,1],[1,5],[2,4],[3,2],[3,5],[4,0],[4,3],[5,2],[5,5]]))

(2)蛮力法用了两个循环,因而其时间复杂度是 O ( n 2 ) O(n^2) On2,分治法由公式有 T ( n ) = T ( n / 2 ) + O ( n ) T(n) = T(n/2) + O(n) T(n)=T(n/2)+O(n),由主定理可以得出其时间复杂度是 O ( n l o g n ) O(nlogn) Onlogn

通过设置100,1000,10000个随机点对,测试蛮力策略和分治策略的用时,从而比较各自的时间复杂度。

image-20240403173629934

实验结果如下:

image-20240403173541725

由此可见蛮力法的时间大致沿着 n 2 n^2 n2的速率增长,而分治法大致沿着 n l o g n nlogn nlogn增长,符合我们的计算结果。

六、实验小结(包括问题和解决方法、心得体会等)

本次作业是分治算法的一个应用,分治和递归相辅相成,通过编写分治算法,让我深刻了解了递归的含义,并且熟悉应用了分治算法解决问题。
串匹配问题是我们在数据结构中就遇到的老朋友,其中的BF算法思想很简单,就是蛮力策略,而KMP算法主要思想是减少重复比较的时间,所以定义了一个next的方法,用来寻找最长前后缀,从而达到不移动主串,只移动子串的快速匹配。
寻找最长连续子序列问题,难点在于想到如果所求序列正好被划分的情况,而后续在三个值中寻找最大值不难分析。
分治策略求众数也是很典型的分治策略的应用,但是和上一题不一样,我们需要先行找到当前最大的众数,然后再应用递归到左、右两个序列中。
最近点对问题应该是最有难度的一道题,蛮力策略很简单,但是分治方法在考虑了左、右两边各自的最近点对之后,还需要考虑是否会有最近的点对穿过了我们的划分线。这其实和寻找最长连续子序列有异曲同工之处,但是在考虑这个问题上,我们只需要从划分线向两侧分别延展已求的最近点对长度就可以,然后寻找在这个区域内的最近点对。
通过本次作业,我对算法有了更进一步的认知,也锻炼了我的编程能力。

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

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

相关文章

Vue2电商前台项目(一):项目前的初始化及搭建

一、项目初始化 创建项目&#xff1a;sudo vue create app 1.项目配置 &#xff08;1&#xff09;浏览器自动打开 在package.json文件中&#xff0c;serve后面加上 --open "scripts": {"serve": "vue-cli-service serve --open","buil…

我与C++的爱恋:类与对象(一)

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;我与C的爱恋 ​C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。 C是基于面向对象的&#xff0c;关注的是对象&…

Tomcat安装部署及JavaEE项目创建

一.Tomcat下载 官网链接 选择自己需要的版本&#xff08;本次采用Tomcat10&#xff09;下载 二.文件结构 解压下载的文件&#xff0c;其主要文件目录如下&#xff1a; 三.启动Tomcat 找到bin目录下的startup.bat文件&#xff0c;双击运行 启动后出现弹窗&#xff0…

【数据结构】初识数据结构与复杂度总结

前言 C语言这块算是总结完了&#xff0c;那从本篇开始就是步入一个新的大章——数据结构&#xff0c;这篇我们先来认识一下数据结构有关知识&#xff0c;以及复杂度的相关知识 个人主页&#xff1a;小张同学zkf 若有问题 评论区见 感兴趣就关注一下吧 目录 1.什么是数据结构 2.…

Java 面向对象(基础)

1、面向对象的概述及两大要素&#xff1a;类与对象 1. 面向对象内容的三条主线&#xff1a; - Java类及类的成员&#xff1a;&#xff08;重点&#xff09;属性、方法、构造器&#xff1b;&#xff08;熟悉&#xff09;代码块、内部类 - 面向对象的特征&#xff1a;封装、继承…

JMeter+Grafana+influxdb 配置出现transaction无数据情况解决办法

JMeterGrafanainfluxdb 配置出现transaction无数据情况解决办法 一、问题描述二、解决方法 一、问题描述 如下图所示出现application有数据但是transaction无数据情况 二、解决方法 需要做如下设置 打开变量设置如下图打开两个选项 然后再进行后端监听器的设置 如下图所…

数据结构进阶篇 之 【交换排序】(冒泡排序,快速排序递归、非递归实现)

当你觉的自己不行时&#xff0c;你就走到斑马线上&#xff0c;这样你就会成为一个行人 一、交换排序 1.冒泡排序 BubbleSort 1.1 基本思想 1.2 实现原理 1.3 代码实现 1.4 冒泡排序的特性总结 2.快速排序 QuickSort 2.1 基本思想 2.2 递归实现 2.2.1 hoare版 2.2.2 …

NoSQL之Redis

目录 一、关系型数据库与非关系型数据库 1.关系数据库 2.非关系数据库 2.1非关系型数据库产生背景 3.关系型数据库与非关系型数据区别 &#xff08;1&#xff09;数据存储方式不同 &#xff08;2&#xff09;扩展方式不同 &#xff08;3&#xff09;对事物性的支持不同 …

微服务(基础篇-008-es、kibana安装)

目录 05-初识ES-安装es_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1LQ4y127n4?p81&vd_source60a35a11f813c6dff0b76089e5e138cc 1.部署单点es 1.1.创建网络 1.2.加载镜像 1.3.运行 2.部署kibana 2.1.部署 2.2.DevTools 3.安装IK分词器 3.1.在线安装ik…

装修避坑指南 | 定制家具你遇到过哪些坑?福州中宅装饰,福州装修

定制家具时可能会遇到以下一些常见问题&#xff1a; 尺寸不准确&#xff1a;由于定制家具需要按需定制&#xff0c;对尺寸的要求很高。如果尺寸不准确&#xff0c;很可能会导致安装困难或者家具不符合空间需求。 材料质量差&#xff1a;有些厂家可能会使用质量较差的材料来降…

[AutoSar]BSW_Memory_Stack_003 NVM与APP的显式和隐式同步

目录 关键词平台说明背景一、implicit synchronization1.1 Write requests 流程 (NvM_WriteBlock)1.2 Read requests 流程 (NvM_ReadBlock)1.3 Restore default requests 流程 (NvM_RestoreBlockDefaults)1.4 Multi block read requests 流程 (NvM_ReadAll)1.5 Multi block wri…

【Python系列】 yaml中写入数据

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

WEB漏洞-文件上传之基础及过滤方式

目录 案例1&#xff1a;百度搜索关键词&#xff0c;找到可能存在漏洞的网页 案例2&#xff1a;不同格式下的文件类型后门测试 案例3&#xff1a;配合解析漏洞下的文件类型后门测试 案例4&#xff1a;本地文件上传漏洞下的文件类型后门测试 案例5&#xff1a;某CVE漏洞利用…

MySQL索引原理

MySQL索引原理 1、Innodb中的B树是怎么产生的呢? 背景1.1、mysql索引使用B树&#xff0c;为什么&#xff1f;1.2、主键索引图示1.3、mysql最好使用自增ID&#xff1a;为什么呢&#xff1f;1.4、高度为3的B树能存多少条数据&#xff1f;a、假设2层b、假设3层 2、索引采用什么数…

从0到1构建uniapp应用-store状态管理

背景 在 UniApp的开发中&#xff0c;状态管理的目标是确保应用数据的一致性&#xff0c;提升用户体验&#xff0c;并简化开发者的工作流程。通过合理的状态管理&#xff0c;可以有效地处理用户交互、数据同步和界面更新等问题。 此文主要用store来管理用户的登陆信息。 重要…

Dubbo入门项目搭建【Dubbo3.2.9、Nacos2.3.0、SpringBoot 2.7.17、Dubbo-Admin 0.6.0】

B站学习视频 基于Dubbo3.2.9、Nacos2.3.0、SpringBoot 2.7.17、Dubbo-Admin 0.6.0、Jdk1.8 搭建的Dubbo学习Demo 一、前置安装 1-1、Nacos 安装 我本地是通过docker-compose来安装nacos的&#xff0c;如果需要其它方式安装可以去百度找下教程&#xff0c;版本是2.3.0的 docker…

新模因币MVP正在受到关注,预计将超越 SHIB 和 BONK

随着一种新的模因币TRUMP进入爆发式增长&#xff0c;加密市场开始对这种基于选举和权利的模因币充满了期待。并引发了人们对过去“玩笑式”模因币未来的疑问&#xff0c;因为当人们审视区块链与现实的意义时&#xff0c;发现&#xff08;SHIB) 和 Bonk (BONK) 等成熟模因币这样…

常见滤波算法(PythonC版本)

简介 受限于MCU自身的ADC外设缺陷&#xff0c;精度和稳定性通常较差&#xff0c;很多场景下需要用滤波算法进行补偿。滤波的主要目的是减少噪声与干扰对数据的影响&#xff0c;让数据更加接近真实值。 一阶低通滤波 一阶低通滤波是一种信号处理技术&#xff0c;用于去除信号中…

在project模式下自定义Implementation Strategies

Implementation Settings定义了默认选项&#xff0c;当要定义新的implementation runs时会使用这些选项&#xff0c;选项的值可以在Vivado IDE中进行配置。 图1展示了“Settings”对话框中的“implementation runs”对话框。要从Vivado IDE打开此对话框&#xff0c;请从主菜单中…

网络通信(一)

网络编程 互联网时代&#xff0c;现在基本上所有的程序都是网络程序&#xff0c;很少有单机版的程序了。 网络编程就是如何在程序中实现两台计算机的通信。 Python语言中&#xff0c;提供了大量的内置模块和第三方模块用于支持各种网络访问&#xff0c;而且Python语言在网络…