【问题标题】:Frequency of non-increasing and non-decreasing subsequences非递增和非递减子序列的频率
【发布时间】:2015-04-06 16:53:28
【问题描述】:

有一个长度为L 的数字序列,我需要计算有多少非递减和非递增的子序列的确切长度。例如,如果我有一个长度为 15 的序列

2、4、11、13、3、5、5、6、3、3、2、4、2、14、15

我看到不递增的子序列是

13、3

6、3、3、2

4, 2

非递减子序列是

2、4、11、13

3、5、5、6

2、4

2、14、15

所以我有

  • 2个长度为2的非递增子序列
  • 1个长度为4的非递增子序列
  • 2个长度为2的非递减子序列
  • 1个长度为3的非递减子序列
  • 2个长度为4的非递减子序列

由于在这种情况下非递减(或非递增)子序列的最大长度可以是 15,因此我考虑通过向量 x 表示频率以表示非递增和 y 用于非递减子序列:

x = (0,2,0,1,0,0,0,0,0,0,0,0,0,0,0)

y = (0,1,1,2,0,0,0,0,0,0,0,0,0,0,0)

将此扩展到长度为 L 的序列的一般情况,我想遍历该序列,并使用循环计算确切长度的子序列的频率。我该怎么做?我将创建长度为 L 的零向量,并且每次遇到长度为 l 的子序列时,我都会将 1 添加到零矩阵的第 l 个元素。

由于我的序列长度为几千,我不会要求 Matlab 编写它们,但我会要求它为我编写特定的频率。

这是一个好方法吗? Matlab中是否有一些功能可以做到这一点?

【问题讨论】:

  • 当您将 [3 3] 视为非递减时,您也应将 [5 5] 视为非递增。否则会变硬。 x 将是 x = (0,3,0,1,0,0,0,0,0,0,0,0,0,0,0) 然后,就像在两个答案中一样。
  • 我犯了一个错误。感谢您指出。 3,3 与 6,3,3,2 一起使用,5,5 与 3,5,5,6 一起使用。事实上,我不能将 3,3 和 5,5 归类为非递减或非递增序列,因为它们是恒定的。我将在问题中进行更正。我会试试这段代码,我会告诉你它是否有效。谢谢!
  • 嗯,你应该称之为“增加”和“减少”,而不是“不减少”和“不增加”
  • 其实没有。非减少意味着它正在增加,但可以包括恒定的子序列。增加就是严格增加。
  • 你似乎不知道你想要什么:D

标签: arrays algorithm matlab sequences


【解决方案1】:

那个可爱的单线解决方案怎么样?

%// vector
A = [2, 4, 11, 13, 3, 5, 5, 6, 3, 3, 2, 4, 2, 14, 15]
%// number of digits in output
nout = 15;

seqFreq = @(vec,x) histc(accumarray(cumsum(~(-x*sign([x*1; diff(vec(:))]) + 1 )), ...
                   vec(:),[],@(x) numel(x)*~all(x == x(1)) ),1:nout).' %'

%// non-increasing sequences -> input +1
x = seqFreq(A,+1)
%// non-decreasing sequences -> input -1
y = seqFreq(A,-1)

x = 0 2 0 1 0 0 0 0 0 0 0 0 0 0 0 

y = 0 1 1 2 0 0 0 0 0 0 0 0 0 0 0 

说明

%// example for non-increasing
q = +1;
%// detect sequences: value = -1
seq = sign([q*1; diff(A(:))]);
%// find subs for accumarray
subs = cumsum(~(-q*seq + 1));
%// count number of elements and check if elements are equal, if not, set count to zero
counts = accumarray(subs,A(:),[],@(p) numel(p)*~all(p == p(1)) );
%// count number of sequences
x = histc(counts,1:nout);

【讨论】:

    【解决方案2】:

    对于非递减序列:

    x = [2, 4, 11,13,3,5,5,6,3,3,2,4,2,14,15]; %// data
    y = [inf x -inf]; %// terminate data properly
    starts = find(diff(y(1:end-1))<0 & diff(y(2:end))>=0);
    ends = find(diff(y(1:end-1))>=0 & diff(y(2:end))<0);
    result = histc(ends-starts+1, 1:numel(x));
    

    对于非递增序列,只需更改infs 的不等式和符号:

    y = [-inf x inf]; %// terminate data properly
    starts = find(diff(y(1:end-1))>0 & diff(y(2:end))<=0);
    ends = find(diff(y(1:end-1))<=0 & diff(y(2:end))>0);
    result = histc(ends-starts+1, 1:numel(x));
    

    【讨论】:

      猜你喜欢
      • 2021-08-14
      • 2014-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多