【问题标题】:Count lengths of sequences of consecutive integers in MATLAB在MATLAB中计算连续整数序列的长度
【发布时间】:2015-01-21 15:21:16
【问题描述】:

我想计算连续整数序列的所有长度并将它们作为向量返回。 例如,考虑向量: x = [1 2 3 4 6 8 9 10 12 13];

长度为:

length([1 2 3 4]) = 4;
length([6]) = 1;
length([8 9 10]) = 3;
length([12 13]) = 2;  

所以,我要生成的结果是:

y = [4 1 3 2] 

我怎样才能做到这一点?

【问题讨论】:

  • 这不是完全重复的,但它涵盖了您的问题等等:printing consecutive numbers
  • 您正在寻找x-(1:length(x)) 的所谓运行长度。所以你可以使用这个答案:Run length encoding
  • @knedlsepp,RLE 中的运行通常被认为是相同值的序列。这两件事当然很接近,但并不完全相同。准确地说。
  • @A.Donda:但是x-(1:length(x))的运行长度不仅接近,而且正是我们想要的......

标签: matlab run-length-encoding


【解决方案1】:

这应该可以解决问题:

y = diff(find(diff([nan ; x(:) ; nan]) ~= 1))

内部diff 查找 +1(序列中断)的步骤,find 确定相应的位置(索引),外部diff 计算序列长度作为差异在序列中断位置之间。 nans 用于通过诱导不同于 1 的 diff 值来确保找到向量开头的序列和结尾的序列。

【讨论】:

  • y = diff(find([0 diff(x) 0] ~= 1)) 避免NaNs?
  • @Divakar,嗯,当然,但我想避免假设数字中不能有 0(或 -2、-1、...)。 Nans 并没有真正造成问题,是吗?
  • 或者,可以先做内部差异,然后添加 1,就像在 knedlsepps 回答中一样。然而,我发现这在其他方面不必要地复杂......
  • 它适用于小的 x 向量,但我有一个 542474 x 1 列向量,我收到以下错误:'Error using horzcat Dimensions of matrix are concatenated are not compatible.'
  • @Divakar,即使数据中有 nans:nan - nan 又是 nan,因此与 +1 不同。数据中的每个 nan,在开头、结尾或中间某处,在输出中显示为长度为 1 的序列。除非这不是预期的行为,否则我认为没有问题。
【解决方案2】:

A. Donda's answer 的小变化:

  1. 使用diff 来检测大于1 的差异。这会在每次运行的结束 处给出1 值。
  2. 向后累积(使用cumsum)为每次运行分配不同的数字标签。累加是反向进行的,因为第 1 步中的 1 值是在每次运行结束时,而不是在开始时。
  3. 使用histc 计算运行长度。

代码:

y = [diff(x)>1 1];               %// step 1
y = cumsum(fliplr(y));           %// step 2
y = fliplr(histc(y, 1:y(end)));  %// step 3

【讨论】:

  • 为什么要往后累积呢?
  • @A.Donda 因为第 1 步会在每次运行的 end 生成一个。我会编辑澄清
【解决方案3】:

这等于x - (1:length(x))run lengths。因此你可以使用:

runLengths = @(x) diff([0, reshape(find(x(1:end-1)~=x(2:end)),1,[]), numel(x)]);
sequenceCounts = @(x) runLengths(x(:)-(1:numel(x)).');
result = sequenceCounts(x);

【讨论】:

    【解决方案4】:
    x = [1 2 3 4 6 8 9 10 12 13];
    
    consecs = []; % empty vector to store answers
    consec = 1; % initialize
    for I=2:length(x)
        if x(I)==x(I-1)+1 % this one is consecutive with previous
            consec = consec+1;
        else % this one starts a new set of consecutives
            consecs(end+1) =  consec;
            consec = 1;
        end
    end
    consecs(end+1)=consec; % remember to include the last consecutives
    display(consecs)
    

    这是经过测试的,它可以工作。

    【讨论】:

      猜你喜欢
      • 2019-04-11
      • 2021-05-08
      • 1970-01-01
      • 2021-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多