滑动窗口算法(C语言描述)

news2024/11/26 8:20:35

第一种类型:不固定长窗口

问题1:***

C代码1:

#include<stdio.h>
#include<string.h>
#define N 5

int min_len(int len1,int len2)
{
	return (len1 < len2 ? len1:len2);
}

int main()
{
	int target = 0;
    int num[N];
	scanf("%d",&target);
	for(int i = 0;i < N;i++)
	{
		scanf("%d",&num[i]);
	}
	
	
	//滑动窗口算法
	int left = 0;
	int right = 0;
	int sum = 0;
	int len = N+1;
	while(right < N)
	{
		sum += num[right];
		while(sum >= target)
		{
			sum -= num[left];
			if(sum < target)
			{
				len = min_len(len,right-left+1);
			}
            left++;
		}
		right++;
	}
	if(len == N+1)
	{
		printf("No such subarray exists!");
	}
	else
	{
		printf("%d",len);
	}
	
	return 0;
}

 问题2:*****

C代码2: 

#include<stdio.h>
#include<string.h>
#define N 80

//向窗口右边添加一个字符,拓宽窗口
void Add_char(char ch,char *window)
{
	int right = strlen(window);
	window[right] = ch;
}
//检查窗口字符串是否满足包含字符串t所有字符且数量不少于t
int Is_ok(char *t,char *window)
{
	int needs[128]={0};
	int windows[128]={0};
	int n=0;
	int w=0;
    int len1 = strlen(window);
    int len2 = strlen(t);
	for(int i=0;i<len1;i++)
	{
		w = (int)window[i];
		windows[w]++;
	}
	for(int j=0;j<len2;j++)
	{
		n = (int)t[j];
		needs[n]++;
	}
	for(int k = 0;k < 128;k++)
	{
		if(needs[k] != 0 && windows[k] < needs[k])
		{
			return 0;//不满足条件
		}
	}
	return 1;//满足条件
}

/*判断当前满足条件的窗口字符串和满足条件的上一次结果字符串比较谁更短,并更新结果。
注意这里不要单纯的把指针result指向新结果(也就是窗口),因为窗口会随着循环而改变,
这样无法保留做中的正确结果,应该把结果字符串赋值给指针result指向的空间*/
void minlen(char *result,char *window)
{
	int result_len = strlen(result);
	int window_len = strlen(window);
	if(result_len > window_len)
    {
        for(int i = 0;i <= window_len;i++)
        {
            result[i] = window[i];
        }
    }
}

//移除窗口左边第1个字符
void remove_char(char *window)
{
    int len = strlen(window);
	for(int i= 0;i < len;i++)
	{
		window[i] = window[i+1];
	}
}

int main()
{
	//定义所需字符数组
	char s[N];//存储字符串s
	char t[N];//存储字符串t
	char window[N]={'\0'};//窗口内的字符串
	char *result = s;//存储找到的满足条件的最短字符串,这里初始化时将其指向字符串s
	
	//输入字符串s和t
	scanf("%s",s);
	scanf("%s",t);
	
	//定义滑动窗口所需变量
	int left = 0;//窗口左边界指针
	int right = 0;//窗口右边界指针
	int end = strlen(s);//字符串s的长度,窗口滑动的终止点
	//开始滑动窗口寻找满足条件的最短字符串
    int flag = 0;
	while(right < end)
	{
		Add_char(s[right],window);//拓宽窗口右边界
		while(Is_ok(t,window)&&left < end)//窗口满足条件,已包含字符串t所有字符且数量也不少
		{
            flag = 1;
			minlen(result,window);//更新最短满足条件子串答案
            remove_char(window);//移除窗口左边第1个字符
			left++;//窗口左边界边界向前滑动
		}
		right++;
	}
    if(flag)
    {
        printf("%s\n",result);
    }
    else
    {
        printf("No such string!\n");
    }
	return 0;
}

问题3:

C代码3:

和上面一个题目差不多,只不过在这里更新答案要加点条件。

#include<stdio.h>
#include<string.h>

//向窗口右边添加一个字符,拓宽窗口
void add_char(int right,char *s,char *window)
{
	int len = strlen(window);
	window[len] = s[right];
}

//检查窗口字符串是否满足包含字符串t所有字符且数量不少于t
int Is_ok(char *window,char *p)
{
	int len_w = strlen(window);
	int len_p = strlen(p);

	int windows[128]={0};
	int ps[128]={0};
	
	int t=0;
	for(int i = 0;i<len_w;i++)
	{
		t = (int)window[i];
		windows[t]++;
	}
	for(int j = 0;j<len_p;j++)
	{
		t = (int)p[j];
		ps[t]++;
	}
	for(int k = 0;k<128;k++)
	{
		if(ps[k] != 0&& ps[k] > windows[k])
		{
			return 0;
		}
	}
	return 1;

}

//移除窗口左边第1个字符
void remove_char(char *window)
{
	int len_w = strlen(window);
	for(int i=0;i<len_w;i++)
	{
		window[i] = window[i+1];
	}
	
}
int main()
{
	//定义字符数组
	char s[20101]={'\0'};
	char p[20101]={'\0'};
	char win[20101]={'\0'};
	//输入字符串s和p
	scanf("%s",s);
	scanf("%s",p);
	//滑动窗口求解答案
	int left = 0;
    int right = 0;
    char *window = win;
    int end = strlen(s);
    
	int flag = 0;//检查s中满足条件的子字符串是否大于0
	int index_arr[1000]={0};
	int x = 0;
    while(right < end)
    {
    	add_char(right,s,window);
    	while(Is_ok(window,p)&&left < end)字符串是异位字符串的前提1是两字符字符种类数量一样
    	{
    		int len1 = strlen(window);
			int len2 = strlen(p);
			if(len1==len2) //字符串是异位字符串的前提2是两字符字符长度一样
			{
				int flag2 = 0;
				for(int j=0;j<len1;j++)
				{
					if(window[j] != p[j])//字符串是异位字符串的必要条件是两字符字符不能一模一样
					{
						flag2 = 1;
					}
				}
				if(flag2)
				{
					index_arr[x] = left;
					x++;
					flag = 1;
				}
				
			}
			remove_char(window);
    		left++;
    	}
    	right++;
    }
    
    if(flag)
    {
    	for(int i=0;i<x;i++)
    	{
    		if(i != x-1)
    		{
    			printf("%d ",index_arr[i]);
    		}
    		else
    		{
    			printf("%d\n",index_arr[i]);
    		}
    	}
    }
    else
    {
    	printf("没有这样匹配的字符串!\n");
    }
	return 0;	
}

问题4:

C代码4:

和前面有一点不一样,主要是窗口移动不太一样。

#include<stdio.h>
#include<string.h>
#define N 80

//向窗口右边添加一个字符,拓宽窗口
void Add_char(char ch,char *window)
{
	int right = strlen(window);
	window[right] = ch;
}
//检查窗口字符串是否满足包含字符串t所有字符且数量不少于t
int Is_ok(char *window)
{
	int windows[128]={0};
	int w=0;
    int len1 = strlen(window);
	for(int i=0;i<len1;i++)
	{
		w = (int)window[i];
		windows[w]++;
	}
	for(int k = 0;k < 128;k++)
	{
		if(windows[k] > 1)
		{
			return 0;//不满足条件
		}
	}
	return 1;//满足条件
}

/*判断当前满足条件的窗口字符串和满足条件的上一次结果字符串比较谁更短,并更新结果。
注意这里不要单纯的把指针result指向新结果(也就是窗口),因为窗口会随着循环而改变,
这样无法保留做中的正确结果,应该把结果字符串赋值给指针result指向的空间*/
void maxlen(char *result,char *window)
{
	int result_len = strlen(result);
	int window_len = strlen(window);
	if(result_len < window_len)
    {
        for(int i = 0;i <= window_len;i++)
        {
            result[i] = window[i];
        }
    }
}

//移除窗口左边第1个字符
void remove_char(char *window)
{
    int len = strlen(window);
	for(int i= 0;i < len;i++)
	{
		window[i] = window[i+1];
	}
}

int main()
{
	//定义所需字符数组
	char s[N];//存储字符串s
	char window[N]={'\0'};//窗口内的字符串
	char result[N]={'\0'};//存储找到的满足条件的最短字符串,这里初始化时将其指向字符串s
	
	//输入字符串s和t
	scanf("%s",s);
	
	//定义滑动窗口所需变量
	int left = 0;//窗口左边界指针
	int right = 0;//窗口右边界指针
	int end = strlen(s);//字符串s的长度,窗口滑动的终止点
	//开始滑动窗口寻找满足条件的最短字符串
    int flag = 0;
	while(right < end)
	{
		Add_char(s[right],window);//拓宽窗口右边界
		if(Is_ok(window)&&left < end)//窗口满足条件,已包含字符串t所有字符且数量也不少
		{
            flag = 1;
			maxlen(result,window);//更新最短满足条件子串答案
        }
        else
        {
        	remove_char(window);//移除窗口左边第1个字符
			left++;//窗口左边界边界向前滑动
		}
		right++;
	}
	
    if(flag)
    {
        printf("%d\n",strlen(result));
    }
    else
    {
        printf("No such string!\n");
    }
    
	return 0;
}

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

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

相关文章

被面试官问到分布式ID,别再傻乎乎只会答雪花算法了...

文章目录 1. 分布式ID2. 数据库主键自增3. 数据库号段模式4. Redis自增5. UUID6. Snowflake (雪花算法)7. Leaf (美团分布式ID生成系统)7.1 Leaf-segment 号段方案7.1.2 双buffer优化 7.2 Leaf-snowflake方案7.3 Leaf-snowflake Demo 1. 分布式ID 在分布式系统中&#xff0c;通…

GEE:使用中文做变量和函数名写GEE代码

作者&#xff1a;CSDN _养乐多_ 啊&#xff1f;最近在编写GEE代码的时候&#xff0c;无意中发现 JavaScript 已经能够支持中文字符作为变量名和函数名&#xff0c;这个发现让我感到非常兴奋。这意味着以后在编程过程中&#xff0c;我可以更自由地融入中文元素&#xff0c;不再…

ubuntu20.04 vins-fusion 运行记录

过程记录 环境&#xff1a; ubuntu20.04 opencv4.2.0(此次使用) 3.3.1(其他程序在使用) vins-fusion vision_opencv 1.下载VINS-Fusion和cv_bridge&#xff0c;并进行修改&#xff0c;方便使用opencv4.2.0和对应的cv_bridge。 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src…

jetty嵌入式开发及spring整合quartz(内存模式)

1 依赖jar包 2 jetty嵌入式开发 2.1 jetty服务启动类 package com.primal.server;import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AbstractHandler;…

[资源推荐] 复旦大学张奇老师科研分享

刷B站的时候首页给我推了这个&#xff1a;【直播回放】复旦大学张奇教授亲授&#xff1a;人工智能领域顶会论文的发表指南先前也散漫地读了些许论文&#xff0c;但没有在一些宏观的方法论下去训练&#xff0c;读的时候能感觉出一些科研的套路&#xff0c;论文写作的套路&#x…

leetCode 583.两个字符串的删除操作 动态规划 + 优化空间复杂度(二维dp、一维dp)

583. 两个字符串的删除操作 - 力扣&#xff08;LeetCode&#xff09; 给定两个单词 word1 和 word2 &#xff0c;返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 示例 1&#xff1a; 输入: word1 "sea", word2 &qu…

3.2.5:VBA对单元格操作的引申

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的劳动效率&#xff0c;而且可以提高数据处理的准确度。我推出的VBA系列教程共九套和一部VBA汉英手册&#xff0c;现在已经全部完成&#xff0c;希望大家利用、学习。 如果…

【Leetcode刷题(数据结构)】:三路划分与三数随机取中的思想实现快速排序的再优化

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法&#xff0c;其基本思想为&#xff1a;任取待排序元素序列中 的某元素作为基准值&#xff0c;按照该排序码将待排序集合分割成两子序列&#xff0c;左子序列中所有元素均小于基准值&#xff0c;右 子序列中所有元素均…

JWT前后端分离在项目中的应用

14天阅读挑战赛当你累了&#xff0c;要学会休息&#xff0c;而不是放弃&#xff01; 目录 一、JWT简介 1.1 什么是JWT 1.2 为什么要使用JWT&#xff0c;与session的区别 1.3 JWT组成及工作原理和流程 二、JWT工具类解析 2.1 生成JWT 2.2 解析oldJwt 2.3 复制JWT并延时…

4.04 用户中心-我的订单评价

内容实现效果&#xff1a; 代码实现内容查看&#xff1a; http://www.gxcode.top/code

Unity中Shader光照模型Blinn-Phong原理及实现

文章目录 前言一、Blinn-Phong原理二、Blinn-Phong实现最终代码 前言 Unity中Shader光照模型Blinn-Phong原理及实现&#xff0c;也是经验型光照模型。和Phong模型一样&#xff0c;都是用于实现高光效果 一、Blinn-Phong原理 可以看出&#xff1a;Blinn-Phong模型和Phong模型不…

排序:如何用快排思想在O(n)内查找第K大元素?

文章来源于极客时间前google工程师−王争专栏。 冒泡排序、插入排序、选择排序三种排序算法&#xff0c;时间复杂度都是O(n^2)&#xff0c;比较高&#xff0c;适合小规模数据的排序。 归并排序和快速排序两种时间复杂度O(nlogn)的排序算法&#xff0c;适合大规模的数据排序&am…

未授权和代码执行漏洞特征和检测方法

文章目录 一、Redis未授权访问二、MongoDB未授权访问三、Elasticsearch未授权访问四、Rsync未授权访问五、Windows RDP远程代码执行漏洞&#xff08;CVE-2019-0708&#xff09;六、Tomcat Web控制台弱口令七、WebLogic控制台弱口令&反序列化系列漏洞八、WebLogic SSRF(无检…

微服务设计原则:构建弹性和可维护的应用

文章目录 1. 单一职责原则2. 独立性和自治性3. 弹性和容错性4. API 网关5. 日志和监控6. 版本管理7. 自动化部署和持续集成8. 安全性9. 数据一致性10. 文档和通信拓展思考结论 &#x1f389;欢迎来到架构设计专栏~微服务设计原则&#xff1a;构建弹性和可维护的应用 ☆* o(≧▽…

Linux环境下Qt应用程序安装器(installer)制作

本文介绍Linux环境下Qt应用程序安装器(installer)的制作。 安装器(installer)是将应用程序安装到操作系统平台的可执行文件&#xff0c;它采用向导式对话框指导用户安装应用程序&#xff0c;如我们在Windows操作系统安装Office软件时&#xff0c;有1个向导让你选择安装哪些组件…

力扣:611. 有效三角形的个数

今日为大家分享一道力扣611有效三角形的个数&#xff01;本文将会为大家为大家讲解题目&#xff0c;然后算法思路&#xff0c;最后再进行代码的实现&#xff01;希望看完本文能对读者有一定的收获&#xff01; 一、题目描述 通过题目的描述可以看出&#xff0c;意思是给定一个…

[产品体验] GPT4识图功能

[产品体验] GPT4识图功能 图片配文字超强的OCR能力知识问答多图解释 打开chatgpt的时候突然发现能用识图了&#xff0c;赶紧去体验一下&#xff0c;大大的震撼… 图片配文字 超强的OCR能力 我传上去的图片并不清晰… 还能准确识别&#xff0c;orz &#xff01; 知识问答 多…

代码随想录Day18 LeetCode235 二叉搜索树的公共祖先 T701二叉搜索树中的插入操作 T140 删除二叉搜索树中的公共节点

LeetCode T235 二叉搜索树的公共祖先 题目链接235. 二叉搜索树的最近公共祖先 - 力扣&#xff08;LeetCode&#xff09; 题目思路 此题不涉及遍历顺序. 关于二叉搜索树的定义,这里我就不过多赘述了,前面几篇都说清楚了,根节点比左子树元素都大,比右子树元素都小,这道题我们就可…

计算机体系结构和操作系统

这篇文章的主要内容是冯诺依曼计算机体系结构和操作系统的理解。 目录 一.冯诺依曼计算机体系结构 二.操作系统的理解 一.冯诺依曼计算机体系结构 如图是冯诺依曼计算机体系结构&#xff0c;计算机本质就是对数据进行处理的机器&#xff0c;图中&#xff0c;数据从输入设备交给…