算法设计与分析实验报告c++java实现(ACM面试题、字符串匹配算法、循环赛日程安排问题、分治法求解最大连续子序列和、动态规划法求解最大连续子序列和)

一、 实验目的

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

二、实验任务

1、【ACM、面试题】求解按“最多排序”到“最小排序”的顺序排列问题。一个序列中的“未排序”的度量是相对于彼此顺序不一致的条目对的数量,例如,在字母序列“DAABEC”中,该度量为5,因为D大于右边是4个字母,E大于其右边的1个字母。该度量称为该序列的逆序数。序列“AACEDGG”只有一个逆序对(E和D),它几乎被排序好了,而序列“ZWQM”有6个逆序对,它是未排序的,恰好是反序。
你需要对若干个DNA序列(仅包含4个字母A、C、G和T的字符串)分类,注意是分类而不是按字母顺序排序,而是按照“最多排序”到“最小排序”的顺序排列,所有DNA序列的长度都相同。
输入:第一行包含两个整数:n(0<n≤50)表示字符串长度,m(0<m≤100)表示字符串个数。后面是m行,每行包含一个长度为n的字符串。
输出:按“最多排序”到“最小排序”的顺序输出所有字符串。若两个字符串的逆序对个数相同,按原始顺序输出它们。
2、字符串匹配算法(BF,KMP)
给定一个文本,在该文本中查找并定位任意给定字符串。
3、循环赛日程安排问题
设有n=2k个选手要进行网球循环赛,要求设计一个满足以下要求的比赛日程表:
(1)每个选手必须与其他n-1个选手各赛一次;
(2)每个选手一天只能赛一次。
4、采用分治法求解最大连续子序列和问题
给定一个有n(n≥1)个整数的序列,要求求出其中最大连续子序列的和。
例如:
序列(-2,11,-4,13,-5,-2)的最大子序列和为20
序列(-6,2,4,-7,5,3,2,-1,6,-9,10,-2)的最大子序列和为16。
规定一个序列最大连续子序列和至少是0(长度为0的子序列),如果小于0,其结果为0。
5、 采用动态规划法求解最大连续子序列和问题

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

实验设备:Win10 电脑
开发工具:Visual Studio 2019
编程语言:C/JAVA

四、实验过程设计(算法设计过程)

(一)、DNA序列分类

1、算法分析:
输入字符的时候可以利用string对象来处理。在计算逆序对时要按照逆序对从小到大的顺序输出,这里有个小技巧,多定义一个数组来存放原始顺序的逆序对数,然后对求取到的逆序对进行从小到大的排序,最后将备用存放逆序对的数组数据跟排好序的进行比较,然后对应原始下标输出对应的字符串即可。

2、代码实现:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;int n, m;
string a[55];
int t[110]={0},r[110];int s(string  a)
{int sum = 0;for(int i = 0; i < a.length()-1; i++)for(int j = i+1; j < a.length(); ++j)if(a[i] > a[j])sum++;return sum;
}int main()
{int x = 0;cout << "请输入字符串长度和字符串个数:\n"; scanf("%d%d",&n,&m);cout << "请输入所有的字符串:\n";for (int i = 0; i < m; ++i){cin >> a[i];}for(int i = 0; i < m; i++){ t[i] = s(a[i]);r[i] = t[i];}sort(t,t+m);cout << "=================\n";cout << "排序后的字符串顺序为:\n";for(int i = 0; i < m; i++)for(int j = 0; j < m; j ++){if(t[i] == r[j])cout << a[j] << endl;}return 0;}

DNA序列分类
1、实验结果

img

2、算法复杂度分析
时间复杂度:O(n^2)

二)、字符串匹配

1、算法分析:
首先,原字符串和子串左端对齐,比较第一个字符,发现不相等,子串向后移动,直到子串的第一个字符能和原字符串匹配。 当A匹配上之后,接着匹配后续的字符,直至原字符串和子串出现不相等的字符为止。参见kmp算法。

2、代码实现:

#include "vector"
#include "string"
#include <iostream>
#include "algorithm"using namespace std;//计算模式P的部分匹配值,保存在next数组中  
void MakeNext(const string &P, vector<int> &next)
{int q,k;//k记录所有前缀的对称值  int m = P.size();//模式字符串的长度  next[0] = 0;//首字符的对称值肯定为0  for (q = 1, k = 0; q < m; ++q)//计算每一个位置的对称值  {//k总是用来记录上一个前缀的最大对称值  while (k > 0 && P[q] != P[k])k = next[k - 1];//k将循环递减,值得注意的是next[k]<k总是成立  if (P[q] == P[k])k++;//增加k的唯一方法  next[q] = k;//获取最终值  }
}void KmpMatch(const string &T, const string &P, vector<int> &next)
{int n, m;n = T.size();m = P.size();MakeNext(P, next);for (int i = 0, q = 0; i < n; ++i){while (q > 0 && P[q] != T[i])q = next[q - 1];if (P[q] == T[i])q++;if (q == m){cout << "模式文本的偏移为:" << (i - m + 1) << endl;q = next[q - 1];//寻找下一个匹配}}
}int main()
{system("color 0A");vector<int> next(20,0);//保存待搜索字符串的部分匹配表(所有前缀函数的对称值)string T = "abcdefgikjhgdjahfsdhgfusgr";//文本string P = "sdhg";//待搜索字符串cout <<"文本字符串:"<< T << endl;cout <<"模式字符串:"<< P << endl;KmpMatch(T, P, next);return 0;
}

字符串匹配
1、实验结果

img

2、算法复杂度分析
时间复杂度:O(m+n)

(三)、循环赛日程安排

1、算法分析:

按照要求,可以将比赛表设计成一个n行n-1列的二维表,其中第i行第j列的元素表示和第i个选手在第j天比赛的选手号。采用分治策略,可将所有参加比赛的选手分成两部分, n = 2 k n=2^k n=2k个选手的比赛日程表就可以通过 n = 2 ( k − 1 ) n=2^{(k-1)} n=2k1个选手的的比赛日程表来决定。递归的执行这样的分割,直到只剩下两个选手,比赛日程表的就可以通过这样的分治策略逐步构建。

假设有 2 1 2^1 21个选手,其安排如下:

12
21

假设有 2 2 2^2 22个选手,其安排如下:

1234
2143
3412
4321

假设有 2 3 2^3 23个选手,其安排如下:

12345678
21446587
34127856
43218765
56781234
65872143
78563412
87654321

根据以上的规律,求解过程可以看作四个部分:

  1. 求左上角子表:左上角子表是前 2 ( k − 1 ) 2^{(k-1)} 2(k1)个选手的比赛前半程的比赛日程。

  2. 求左下角子表:左下角子表是剩余的 2 ( k − 1 ) 2^{(k-1)} 2(k1)个选手的比赛前半程比赛日程。这个子表和左上角子表的对应关系式,对应元素等于左上角子表对应元素加 2 ( k − 1 ) 2^{(k-1)} 2(k1)

  3. 求右上角子表:等于左下角子表的对应元素。

  4. 求右下角子表:等于左上角子表的对应元素。

2、代码实现:

#include<stdio.h>
#include<math.h>
#define N 50
void GameTable(int k,int array[][N]);
void print(int k,int array[][N]);         //输出二维数组 
main()
{int k;int array[N][N];printf("参赛选手的人数为n(n=2^k),请输入k 的值:");do{scanf("%d",&k);if(k>0){GameTable(k,array);print(k,array);}elseprintf("您输入的数据有误,请重新输入"); }while(k!=0);//排除输入错误k值}
void GameTable(int k,int array[][N])//数组下标从1开始
{int i,j,s,t;int n=1;for(i=1;i<=k;i++)n*=2;                       //求总人数for(i=1;i<=n;i++)array[1][i]=i;                  //第一行排1-8int m=1;                          //用来控制每一次填表时i行j列的起始填充位置for(s=1;s<=k;s++)                 //s指对称赋值的总循环次数,即分成几大步进行制作日程表{n=n/2;for(t=1;t<=n;t++)              //t指明内部对称赋值的循环次数for(i=m+1;i<=2*m;i++)for(j=m+1;j<=2*m;j++){array[i][j+(t-1)*m*2]=array[i-m][j+(t-1)*m*2-m];       //右上角等于左上角的值array[i][j+(t-1)*m*2-m]=array[i-m][j+(t-1)*m*2];       //左下角等于右上角的值}m*=2;}}
void print(int k,int array[][N])
{int i,j;int num=pow(2,k);printf("%d人的循环赛日程表如下:\n",num);for(i=1;i<=num;i++)                           //输出二维数组 {for(j=1;j<=num;j++){printf("%d\t",array[i][j]);}printf("\n");}
}

循坏日程赛安排
1、实验结果

img

2、算法复杂度分析
时间复杂度:O(2^k * 2^k)。

(四)、(分治)最大连续子序列和

1、算法分析:
1.将一个长度为n的序列,一分为二变为两个长度为n/2的子序列,继续将子序列们一分为二,直到每个子序列只含有1个整数。
2.此时问题已经足够小,“最大子序列和”有以下三种情况:左边序列的最大子序列和、右边序列的最大子序列和和处在中间位置上的最大子序列和,我们通过比较,得到三者中的最大值。
3.再将这些“小问题”合并,使用同样的比较方法逐步向上合并这些“左右序列”,直到得到整个序列的最大子序列和,解决问题。

2、代码实现:

#include<stdio.h>
#define MAXSIZE 100int max3(int a,int b,int c)
{if(a>b) return a>c?a:c;else return b>c?b:c;
}int MaxSubseqSum(int a[],int left,int right)
{int maxLeftSum,maxRightSum,maxMidSum;int maxLeftBorderSum,LeftBorderSum;int maxRightBorderSum,RightBorderSum;int mid;int i;if(left==right)	//递归出口,子序列只有一个元素时return a[left];mid=(left+right)/2;	//求中间位置maxLeftSum=MaxSubseqSum(a,left,mid);	//求左边序列的最大子序列和maxRightSum=MaxSubseqSum(a,mid+1,right);	//求右边序列的最大子序列和maxLeftBorderSum=0;LeftBorderSum=0;for(i=mid;i>=left;i--)	//从中间位置向左找靠边界的最大子序列{LeftBorderSum+=a[i];if(LeftBorderSum>maxLeftBorderSum)maxLeftBorderSum=LeftBorderSum;}maxRightBorderSum=0;RightBorderSum=0;for(i=mid+1;i<=right;i++)	//从中间位置向右找靠边界的最大子序列{RightBorderSum+=a[i];if(RightBorderSum>maxRightBorderSum)maxRightBorderSum=RightBorderSum;}maxMidSum=maxLeftBorderSum+maxRightBorderSum;	//得到处在中间位置上的最大子序列和return max3(maxLeftSum,maxRightSum,maxMidSum);
}int MaxNum(int a[],int left,int right)
{int maxLeft,maxRight;int mid;if(left==right)return a[left];mid=(left+right)/2;maxLeft=MaxNum(a,left,mid);maxRight=MaxNum(a,mid+1,right);return maxLeft>maxRight?maxLeft:maxRight;
}int main()
{int a[MAXSIZE];int count=0;int i,n;printf("序列长度:");scanf("%d",&n);printf("输入整数序列:");for(i=0;i<n;i++){scanf("%d",&a[i]);if(a[i]<=0)count++;}if(count==n)	//判断是否含有正整数printf("最大子序列和:%d\n",MaxNum(a,0,n-1));elseprintf("最大子序列和:%d\n",MaxSubseqSum(a,0,n-1));}

(分治)最大连续子序列和
1、实验结果

img

2、算法复杂度分析
时间复杂度:O(nlog(n))

(五)、(动态规划)最大连续子序列和

1、算法分析:

  1. 动态规划算法:求最大连续子序列
    1) k[j] 表示最大连续子序列最后一个元素,dk[j]表示最大连续子序列和
    2)最大连续子序列和为从 dk[i] ~ dk[j]
  2. 分两种情况:
    1)最大和为k[j]。它之前的序列和都小于k[j]
    2)最大和为dk[j-1]+k[j]。
    3.得到状态转移方程:
    dk[j] = max{dk[j-1]+k[j], k[j]} 边界为 dk[0] = j[0]
  3. 动态规划算法计算特点(步骤):
    从后往前算,每步计算结果都记录进表。
    计算结束后,再遍历记录表。

2、代码实现:

import java.util.Scanner;public class MaxSubSequence {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入子序列长度:");int N = sc.nextInt();System.out.println("请输入子序列:");int[] A = new int[N];for (int i = 0; i < A.length; i++) {A[i] = sc.nextInt();}int ThisSum, MaxSum, j;ThisSum = MaxSum = 0;for (j = 0; j < N; j++) {ThisSum += A[j];if (ThisSum > MaxSum)MaxSum = ThisSum;else if (ThisSum < 0)ThisSum = 0;}System.out.println("最大子序列和位:" + MaxSum);}
}

(动态规划)最大连续子序列和
1、实验结果

img

2、算法复杂度分析
时间复杂度:0(n)

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

分治法,字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。本次实验增加了动手编码能力,对算法设计有了更进一步的认识,但是技术上的缺陷,编码能力上存在的短板,在今后的实验中还需要加大练习力度。

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

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

相关文章

linux重定向符号

将ls命令执行结果重定向到a文件中 将错误ls命令执行结果重定向到a文件中&#xff08;这里用到前面的标准错误输出重定向&#xff09;

科研学习|可视化——相关性结果的可视化

一、相关性分析介绍 相关性分析是指研究两种或者两种以上的变量之间相关关系的统计分析方法&#xff0c;一般分析步骤为&#xff1a; 1&#xff09;判断变量间是否存在关联&#xff1b;2&#xff09;分析关联关系&#xff08;线性/非线性&#xff09;、关联方向&#xff08;正相…

上海人工智能实验室的书生·浦语大模型学习笔记(第二期第三课——上篇)

书生浦语是上海人工智能实验室和商汤科技联合研发的一款大模型&#xff0c;这次有机会参与试用&#xff0c;特记录每次学习情况。 一、课程笔记 本次学习的是RAG&#xff08;Retrieval Augmented Generation&#xff09;技术&#xff0c;它是通过检索与用户输入相关的信息片段…

基于SSM的大学生兼职平台的设计与实现需求(源码+配套文档)

基于SSM的大学生兼职平台的设计与实现需求&#xff08;源码配套文档&#xff09; 摘 要 信息社会、信息时代造就了现在我们所拥有的科技生活。各种关于生活、社团的互联网软件逐步的走向了百姓的生活当中&#xff0c;移动互联网在当下的时代中有着非常成熟的应用&#xff…

【nodejs基础学习三-浏览器偏好设置】

系列文章目录 第一章 nodejs基础学习–注释、变量、运算符、字符串、函数&#xff08;一&#xff09; 第二章 nodejs基础学习–循环、对象字符、模块导入出&#xff08;二&#xff09; 第三章 nodejs基础学习三-浏览器设置 系列文章目录一、开发者模式二、web偏好设置 一、开发…

1.网络编程-网络协议

目录 网络编程是什么 网络编程三要素 OSI七层网络模型 TCP/IP五层模型 SSL/TLS 是哪层协议 网络编程是什么 网络编程是计算机科学中的一个重要领域&#xff0c;它涉及到编写能够在网络环境中进行通信的程序。网络编程的核心目标是使不同的设备能够通过网络交换信息&#…

【前端Vue】Vue3+Pinia小兔鲜电商项目第5篇:整体认识和路由配置,本资源由 收集整理【附代码文档】

Vue3ElementPlusPinia开发小兔鲜电商项目完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;认识Vue3&#xff0c;使用create-vue搭建Vue3项目1. Vue3组合式API体验,2. Vue3更多的优势,1. 认识create-vue,2. 使用create-vue创建项目,1. setup选项的写法和执行…

万亿资产规模,一个指标平台,银行业数据赋能经营的最佳实践

为了适应经营环境变化&#xff0c;企业的发展模式需要转向高质量发展。在数字经济时代&#xff0c;借助数字化手段实现数字化经营&#xff0c;是企业实现高质量发展的必由之路。 指标平台逐渐成为企业数据基础设施中的重要组成部分。企业可以借助指标平台对数据资产进行便捷化…

全面的网络流量监控

流量监控指的是对数据流进行的监控&#xff0c;通常包括出数据、入数据的速度、总流量。通过网络流量监控&#xff0c;组织可以确保只有业务关键型流量通过网络传输&#xff0c;并限制不需要的网络流量&#xff0c;从而提高网络效率&#xff0c;又可以防止停机、减少 MTTR、帮助…

实验8 内置对象session

一、实验目的 掌握怎样在JSP中使用内置对象session 二、实验项目内容&#xff08;实验题目&#xff09; 编写代码&#xff0c;掌握session的用法。【参考课本4.6.5 】 三、源代码以及执行结果截图&#xff1a; choiceGrade.jsp <% page language"java" content…

ad原理图库的创建及引入

SCH是原理图库。 PCB是封装库。 法1 小器件 1.创建lib 保存路径 2.创建器件 3.绘制器件 右击》放置》选择要放置的东西》左键放置&#xff0c;右键结束。 放置引脚快捷↓ 【Name】:用于输入库元件引脚的功能名称.  【Designator】:用于设置引脚的编号 选择器件后电机T…

EEPROM读写案例(以AT24C02为例)

本篇文章主要是在学习单片机串行接口时的学习经历&#xff0c;主要侧重于驱动程序的讲解。下文将通过ESP32S3、STM32两款MCU进行编写驱动案例。 1、AT24C02简要说明 AT24C02是美国微芯科技公司生产的电擦写式只读存储器系列中的一款&#xff0c;其容量为2K位&#xff08;即256字…

每日OJ题_BFS解决FloodFill④_力扣130. 被围绕的区域

目录 力扣130. 被围绕的区域 解析代码 力扣130. 被围绕的区域 130. 被围绕的区域 难度 中等 给你一个 m x n 的矩阵 board &#xff0c;由若干字符 X 和 O &#xff0c;找到所有被 X 围绕的区域&#xff0c;并将这些区域里所有的 O 用 X 填充。 示例 1&#xff1a; 输入&…

libVLC 视频界面分割

先看看分割后的界面吧&#xff0c;根据分割的数量&#xff0c;来分割视频画面。 其实视频界面分割很简单&#xff0c;看过叠加窗口的这篇文章&#xff0c;不难理解&#xff0c;如何分割。 libVLC 视频窗口上叠加透明窗口-CSDN博客 如果还是不懂的话&#xff0c;我讲解一下原理…

原码的除法运算

目录 王道考研ppt&#xff1a; 个人理解&#xff1a; 手算整数的除法&#xff1a; ​编辑 手算二进制的除法&#xff1a; 用机器实现除法&#xff1a; 方法一&#xff1a;恢复余数法 第二种方法&#xff1a;加减交替法 王道考研ppt&#xff1a; 个人理解&#xff1a; 手…

政安晨:【深度学习神经网络基础】(三)—— 激活函数

目录 线性激活函数 阶跃激活函数 S型激活函数 双曲正切激活函数 修正线性单元 Softmax激活函数 偏置扮演什么角色&#xff1f; 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: 政安晨的机器学习笔记 希望政安晨的博客能够对您有所裨…

【完全背包求方案数问题】AcWing1023.买书(赋练习题目)

【题目链接】活动 - AcWing 输入样例1&#xff1a; 20输出样例1&#xff1a; 2输入样例2&#xff1a; 15输出样例2&#xff1a; 0输入样例3&#xff1a; 0输出样例3&#xff1a; 1 【代码】 //1023.买书——完全背包问题#include<bits/stdc.h>using namespace st…

IP定位的原理及应用场景

IP定位&#xff0c;即通过IP地址来确定一个设备或用户所在的大致地理位置&#xff0c;是一项在现代网络时代中愈发重要的技术。它广泛应用于网络安全、数据分析、广告投放等多个领域&#xff0c;为人们的生活和工作带来了极大的便利。本文将从IP定位的原理、实现方式、应用场景…

百度Create AI开发者大会剧透丨用好三大AI神器 ,人人都是开发者

程序员会消失&#xff0c;真的吗&#xff1f;大模型的下一站是什么&#xff1f;开发者的机会在哪里&#xff1f;什么才是最好用的AI应用开发工具&#xff1f;在4月16日举办的2024百度Create AI开发者大会上&#xff0c;百度创始人、董事长兼首席执行官李彦宏将就这些备受瞩目的…

Vue的学习之旅-part4

Vue的学习之旅-part1 vue的自带指令v-if v-else-if v-else虚拟DOM的复用v-show 与 v-if 的不同之处&#xff1a;v-if v-show各自合适的使用位置&#xff1a; v-for 循环v-for 循环遍历 :key"item" 绑定key&#xff0c;区分循环的内容循环的应用&#xff1a; 前几篇博…