寻找列表连续的子列


问题描述

假定有一个列表[1,2,3,4,6,9,7,8],请将连续的分为一组,不连续的单独成组。结果为:[[1,2,3,4],[6],[9],[7,8]]

拓展区
类似的问题:
第35题:最大连续子序列
第36题:最大非连续子序列

C语言

#include <stdio.h>
int main(){
 int i =0;
 int j =0;
 int k =0;
 int i1=0;
 int j1=0;
 int a[] = {2,3,4,11,17,20,21,22,23,24,25,26};
 
 int b[5][10]={
  {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
  {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
  {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
  {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
  {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
 };
 
 for (i;i<=11;i++){
  b[j][k] = a[i];
  k++;
  if(a[i+1] != a[i] + 1){
   j++;
   k=0;
   continue;
  } 
 }
 
 printf("二维数组存储结果\n");
 for (i1=0;i1<5;i1++ ) {
  for (j1=0;j1<10 && b[i1][j1] != -1 ;j1++ ){
   printf("%d ",b[i1][j1]);
  }
  printf("\n");
 }
 
 return 0;
} 

这是同学写的一段代码,据说可以出来。若感兴趣请自测。

python版

刚开始自己写的有点蠢,bug还多,借鉴一下C语言实现思路。其中的核心代码:

 for (i;i<=11;i++){
  b[j][k] = a[i];
  k++;
  if(a[i+1] != a[i] + 1){
   j++;
   k=0;
   continue;
  } 

Python代码:

def newFunction(a):
    """
    寻找连续的天,连续的放在一组,不连续则单独成组
    :param a: list
    :return:
    """
    if len(a)==1:
        return a
    else:
        #寻找连续的day,若不连续则插入‘’
        temp=[]
        for i in range(len(a)-1):
            temp.append(a[i])
            if a[i+1]!=a[i]+1:#DateOffset(days=1)
                temp.append('')
                continue
        #定位前面""的位置
        tmp_index=[num for num,i in enumerate(temp) if not i]
        #找到其在原列表的索引(位置)
        tmp_index=[i-num for num,i in enumerate(tmp_index)]
        #分组节点,如果第一个不是从0开始,则在首位插入0;类似,若最后一位不是len(a),则插入它
        if tmp_index[0]!=0:
            tmp_index.insert(0,0)
        if tmp_index[-1]!=len(a):
            tmp_index.insert(len(a),len(a))
        #保存分组的结果
        result=[]
        for i in range(len(tmp_index)-1):
            result.append(a[tmp_index[i]:tmp_index[i+1]])
        return result

原谅不会数据结构等,只能现学现卖。实现思路:
(1). C语言核心代码的思路是连续的元素直接输出,不连续的换行输出。基于这个思路:连续的直接存储到列表,不连续的将换行符变成''插入列表。

(2). 然后定位到''所在的索引,通过转换确定出其在原列表的位置。

(3). 理论上这里可以通过遍历结束,实力不够,先忽略。笨办法:先构造出完整的切片(索引)区间,通过下述代码实现。

#分组节点,如果第一个不是从0开始,则在首位插入0;类似,若最后一位不是len(a),则插入它
if tmp_index[0]!=0:
   tmp_index.insert(0,0)
if tmp_index[-1]!=len(a):
   tmp_index.insert(len(a),len(a))

(4). 最然按照切片索引区间切割原列表即可。

测试结果

变形应用

可以应用到连续时间序列的查找上,函数需要改动的地方为:

if a[i+1]!=a[i]+1:#DateOffset(days=1)#from pandas.tseries.offsets import *

更新解法:

def func(x):
	tmp=[]
	i=0
	max_len=0
	while i<len(x):
		if len(tmp)==0:
			tmp.append(x[i])
		elif x[i]-tmp[-1]==1 and x[i] not in tmp:
			tmp.append(x[i])
		else:
			tmp=[x[i]]
		max_len=len(tmp) if len(tmp)>max_len else max_len
		print(f'i={i},max_len={max_len},x[i]={x[i]},tmp={tmp}')
		i+=1
	return max_len



欢迎交流!!!

posted @ 2020-08-09 19:20  LgRun  阅读(309)  评论(0编辑  收藏  举报