You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

K语言求整数数组最长连续序列长度的实现问题咨询

K语言求整数数组最长连续序列长度的实现问题咨询

大家好,我最近在尝试用K语言实现从整数列表里找出最长连续数字序列的功能,目前写的代码在第一个测试案例里工作正常,但到第二个案例时结果不符合预期,想请各位帮忙看看怎么修改才能得到正确结果。

先给大家看正常工作的测试案例:

q) list:100 4 200 1 3 2
q)st where (deltas st:asc list)=1
1 2 3 4
q)count st where (deltas st:asc list)=1
4

这段代码能正确输出连续序列1 2 3 4,长度为4,符合预期。

但下面的测试案例就出问题了:

q)list
10 15 1 2 3 4 5 11 12
q)st where (deltas st:asc list)=1
1 2 3 4 5 11 12   // 我预期的结果应该是1 2 3 4 5
q)count st where (deltas st:asc list)=1
7

当前代码把两段连续序列(1-511-12)合并输出了,而我想要的是最长的那一段连续序列,也就是1 2 3 4 5,对应的长度是5。

解决方案思路

要解决这个问题,我们需要先给排序后的数组里的连续数字块分组,再找到长度最长的那个块。可以借助K语言的rle(游程编码)函数实现这个逻辑,具体步骤如下:

  1. 对原始列表排序
  2. 计算排序后列表中相邻元素的差值
  3. rle对差值序列编码,得到连续相同差值的长度和对应值
  4. 筛选出差值为1的块,找到其中长度最长的那个
  5. 根据最长块的位置,从排序后的列表中提取对应连续序列

具体实现代码

针对上述问题案例,修改后的代码如下:

q)list:10 15 1 2 3 4 5 11 12
q)st:asc list  // 先排序列表
q)(l;v):rle 1_deltas st  // 对相邻差值做游程编码,l是块长度,v是对应差值
q)idx:max i where v=1  // 找到差值为1的块中长度最长的那个的索引
q)start:sum l[0:idx]  // 计算该块在排序后列表中的起始位置
q)end:start+l[idx]  // 计算该块的结束位置
q)st[start:end+1]  // 提取对应的最长连续序列
1 2 3 4 5
q)count st[start:end+1]  // 计算最长连续序列的长度
5

代码解释

  • 1_deltas st:计算排序后列表的相邻元素差值,去掉第一个无效差值(deltas的第一个结果是第一个元素本身),得到真正的相邻差序列。
  • rle函数会把连续相同的差值分成块,比如这个案例的差值序列是1 1 1 1 6 1 4,编码后得到块长度l:4 1 1 1、对应差值v:1 6 1 4
  • 通过max i where v=1找到差值为1的块中长度最大的那个索引(这里第一个块长度4是最大的,索引为0)。
  • 最后计算该块在排序后列表中的起止位置,提取元素就得到了最长连续序列。

如果存在多个长度相同的最长连续序列,这段代码会返回第一个出现的序列。如果需要获取所有最长序列,可以把idx的计算改成idxs:i where v=1 and l=max l where v=1,再逐个提取对应序列即可。

备注:内容来源于stack exchange,提问作者Rajasekhar

火山引擎 最新活动