需求

对于一个数组array = ["n","v","l","f",...,"y","c","k"];

  • input

    • 当前位置 index
    • 数组的长度 arraySize
    • 基于当前位置,(前/后)滑动窗口的元素数目 windowSize
      • 即 滑动窗口(假定:包含当前元素 array[idx]) 总长:2*windowSize+1
  • output
    • 滑动窗口中的元素下标数组

      • 形如

        • 【中间】idx=3,arraySize=7,windowSzie=2 => [1,2,3,4,5]
        • 【偏前】idx=0,arraySize=7,windowSzie=2 => [5,6,0,1,2]
        • 【偏后】idx=6,arraySize=7,windowSzie=2 => [4,5,6,1,0]

实现思路

  • [1] 循环队列
  • [2] 充分利用模运算的特点:最左边下标 (idx-windowSize)%arraySize 与 最后边下标(idx+windowSize)%arraySize可计算出来

源码 一

利用思路2,节省更多计算资源。

目前存在一种bug,比如 (2,10,3)

class CollectionUtil:
def window(idx,arraySize,windowSize,containsCenterIdx=True): # 实现滑动窗口
"""
获得当前位置的滑动窗口[元素的下标数组]
-----------------------------------
+ idx : 当前位置下标
+ containsCenterIdx : 返回结果中,是否需要包含idex索引本身
+ 获得长为arraySize的列表中,以idex为中心,前后分别长windowSize个元素的的滑动窗口的元素下标数组
+ 默认数组下标最小为0
+ 滑动窗口总长 2*windowSize+1
+ 博文 [url] https://www.cnblogs.com/johnnyzen/p/10905958.html
"""
if idx>=arraySize or idx < 0 or arraySize<1:
raise ValueError("idx '",idx,"' out of arraySize '",arraySize,"' or them is error value!");
if 2*windowSize+1 > arraySize:
raise ValueError("2*windowSize+1 > arraySize! [ windowSize:",windowSize," | arraySize:",arraySize," ]");
window = [];
leftStart = (idx-windowSize)%(arraySize-1); # 1,10,3 -> 7,8,9,0,1,2,3
rightEnd = (idx+windowSize)%(arraySize-1); # 9 0 1 2
isRightWindowContinuous = True if idx+windowSize==rightEnd else False; # 判断右半窗口是否连贯
for i in range(leftStart,leftStart + windowSize): # range(m,n) = [m,n)
window.append(i);
pass;
if containsCenterIdx == True:
window.append(idx);
if isRightWindowContinuous == True:
for i in range(rightEnd-windowSize+1,rightEnd+1): # 2-4+1
window.append(i);
pass;
else : # 不连贯 即 右半窗口,一部分在数组开头,一部分在数组结尾
for i in range(idx+1,arraySize-1+1):
window.append(i);
pass;
for i in range(0,rightEnd):
window.append(i);
pass;
return window;

测试

print(CollectionUtil.window(1,10,3)); # [7, 8, 9, 1, 2, 3, 4]
print(CollectionUtil.window(9,10,3)); # [6, 7, 8, 9, 0, 1, 2]
print(CollectionUtil.window(8,10,4)); # [4, 5, 6, 7, 8, 9, 0, 1, 2]
print(CollectionUtil.window(7,10,4)); # [3, 4, 5, 6, 7, 8, 9, 0, 1]
# print(CollectionUtil.window(3,7,2)); # [1,2,3,4,5]
# print(CollectionUtil.window(0,7,2)); # [5,6,0,1,2]
# print(CollectionUtil.window(6,7,2)); # [4,5,6,0,1]

源码 二

利用循环队列,目前没有bug。

class CircularQueue: # 循环队列
def __init__(self):
self.queue = []*0; # 空列表
self.cursor = 0; def push(self,eles):
if isinstance(eles,Iterable) == True: # 可遍历类型 字符串("dsvvdsv")、列表、元组、字典、集合等
for ele in eles:
self.queue.append(ele);
pass;
else : # 其他,默认为 单元素处理
self.queue.append(eles); def pop(self,index=-1):
return self.queue.pop(index); # index=-1 : 移除最后一个元素
pass; def index(self,obj):
return self.queue.index(obj); def length(self):
return len(self.queue); def next(self,idx=0):
if idx >= len(self.queue)-1:
return {"index":0,"value":self.queue[0]};
else :
return {"index":(idx+1),"value":self.queue[idx+1]}; def prev(self,idx=0):
if idx <=0:
return {"index":(len(self.queue)-1),"value":self.queue[len(self.queue)-1]};
else :
return {"index":(idx-1),"value":self.queue[idx-1]}; def print(self):
print("queue:",self.queue); def window(self,idx,arraySize,windowSize): # 滑动窗口
windowIndexs = [];
for i in range(0,arraySize):
self.push(i); # 初始化
pass;
nextNodeCursor = self.next(idx); # 下一节点游标
prevNodeCursor = self.prev(idx); # 上一节点游标
for i in range(0,windowSize): # 加载前窗口元素
windowIndexs.append(prevNodeCursor["value"]);
prevNodeCursor = self.prev(prevNodeCursor["index"]);
# self.pop(nextNode["index"]);
pass;
windowIndexs.append(idx);
for i in range(0,windowSize): # 加载后窗口元素
windowIndexs.append(nextNodeCursor["value"]);
nextNodeCursor = self.next(nextNodeCursor["index"]);
# self.pop(prevNode["index"]);
pass;
windowIndexs.sort(); # 返回前 排序
return windowIndexs;

测试

print("window:",CircularQueue().window(2,10,3)); # window: [0, 1, 2, 3, 4, 5, 9]

Python之滑动窗口的更多相关文章

  1. python 图片滑动窗口

    METHOD #1: No smooth, just scaling. def pyramid(image, scale=1.5, minSize=(30, 30)): # yield the ori ...

  2. 『Python』图像金字塔、滑动窗口和非极大值抑制实现

    图像金字塔 1.在从cv2.resize中,传入参数时先列后行的 2.使用了python中的生成器,调用时使用for i in pyramid即可 3.scaleFactor是缩放因子,需要保证缩放后 ...

  3. 【剑指Offer】滑动窗口的最大值 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 暴力求解 单调递减队列 日期 题目地址:https://www ...

  4. leetcode 239. 滑动窗口最大值(python)

    1. 题目描述 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 示 ...

  5. 剑指Offer 64. 滑动窗口的最大值 (其他)

    题目描述 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值.例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6 ...

  6. LeetCode 第 3 题:无重复字符的最长子串(滑动窗口)

    LeetCode 第 3 题:无重复字符的最长子串 (滑动窗口) 方法:滑动窗口 滑动窗口模板问题:右指针先走,满足了一定条件以后,左指针向前走,直到不满足条件. 特点:左右指针的方向是一致的,并且是 ...

  7. 【Leetcode堆和双端队列】滑动窗口最大值(239)

    题目 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 示例: 输入 ...

  8. TCP协议可靠性是如何保证之滑动窗口,超时重发,序列号确认应答信号

    原创文章首发于公众号:「码农富哥」,欢迎收藏和关注,如转载请注明出处! TCP 是一种提供可靠性交付的协议. 也就是说,通过 TCP 连接传输的数据,无差错.不丢失.不重复.并且按序到达. 但是在网络 ...

  9. 【LeetCode】480. 滑动窗口中位数 Sliding Window Median(C++)

    作者: 负雪明烛 id: fuxuemingzhu 公众号: 每日算法题 本文关键词:LeetCode,力扣,算法,算法题,滑动窗口,中位数,multiset,刷题群 目录 题目描述 题目大意 解题方 ...

随机推荐

  1. SCU 4442 party 二分图最大点权独立集

    每个青蛙喝黑茶或者红茶或者都可以喝 M个矛盾关系 有矛盾的不能喝同种茶 但你可以花费Wi使得这个青蛙消除所有矛盾 把矛盾当作边 青蛙当作点 如果这两个青蛙只喝不同的一种茶就不建边 题目中保证了不存在奇 ...

  2. Python 获得程序 exe 的版本号

    Python 获得程序 exe 的版本号 python中需要安装 pywin32 包 # based on http://stackoverflow.com/questions/580924/pyth ...

  3. Redis长短链接的区别

    本文介绍了phpredis中与redis建立连接的两种方式:connect(短连接)和pconnect(长连接)的区别. 问题背景: 项目采用LNMP架构,考虑到数据访问性能问题,因此使用redis来 ...

  4. python+Appium自动化:屏幕截图

    屏幕截图 主要是为了程序出现错误时,开发除了可以分析日志之外,还可以进行截图更好地去定位问题. 截图一般有两种方法: 第一种save_screenshot(self,filename) driver. ...

  5. 选择排序Selection_Sort

    基本思想:和冒泡排序.直接插入排序并称为三大简单排序算法.显然,说明它们都很简单

  6. 洛谷P1006 传纸条【dp】

    题目:https://www.luogu.org/problemnew/show/P1006 题意: 给定一个m*n的矩阵,从(1,1)向下或向右走到(m,n)之后向上或向左走回(1,1),要求路径中 ...

  7. Codeforces Round #589 (Div. 2) D. Complete Tripartite(染色)

    链接: https://codeforces.com/contest/1228/problem/D 题意: You have a simple undirected graph consisting ...

  8. 响应json数据之发送ajax的请求

    一.前端异步请求代码: <span style="font-size:14px;">$.ajax ({ type: "POST", //请求的方式 ...

  9. CF732D Exams 二分 贪心

    思路:二分+贪心 提交次数:10次以上 错因:刚开始以为二分(边界,$+1or-1$)写错了,调了半天,后来才发现是$ck()$写错了.开始只判了最后是否小于零,而应该中间一旦小于零就$return\ ...

  10. C#_选择结构,Console的应用,数据类型转换

    1:先看一个顺序结构编程,代码如下: using System; using System.Collections.Generic; using System.Linq; using System.T ...