【问题标题】:Getting patterns out of a binary string从二进制字符串中获取模式
【发布时间】:2019-05-31 01:42:30
【问题描述】:

我有一个长度为 N 的二进制字符串,它是 2 的幂 (N = 2^n)。

我需要提取长度为L 的特定模式,这是2 (L = 2^l) 的幂。

全二叉树中,这些模式应该

  • 从左叶节点(偶数索引)开始
  • 以右叶节点(奇数索引)结束。

这些模式应该包括整个子树的叶子。 我需要提取的模式是,

(1). 0 0 --- 0  (All zero)
(2). 1 1 --- 1  (All one)
(3). 0 0 --- 1  (Only the last right leaf is one). 

例如,如果我有一个二进制字符串N=16,(n=4) 比如 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0,我要解压

  • 索引0 to 7 为模式 (3),

  • 索引8 to 11 为模式 (2) 和

  • 最后一个 4 索引为模式 (1)。

我需要它作为通道解码算法的一部分来修剪二叉树。在 Matlab 中有没有一种有效的方法来做到这一点?

【问题讨论】:

  • 您是否尝试过实际构建该树并递归评估分支?
  • 为了进一步澄清,这些模式可以存在于字符串中的任何位置。但是每个模式都应该从子树最左边的叶子开始,到子树最右边的叶子结束。
  • @CrisLuengo 我添加了我递归实现的代码。
  • 那是很好的代码,我不知道如何显着改进它。我建议您不要使用pattern3_indices = [pattern3_indices ; [st,ed]];,而是使用pattern3_indices(end+1,:) = [st,ed];,这通常更快。任何您可能想要将all 添加到if chunk == pattern3if all(chunk == pattern3)all 是默认应用的,但很高兴明确说明它(我一直在查找 if 与数组的行为是什么)。
  • @CrisLuengo 谢谢!会这样做。

标签: matlab binary-tree


【解决方案1】:

我已经递归地实现了解决方案,如下所示,

s = [0  0  0  1  0  0  0  1  0  0  0  1  0  1  1  1  0  0  0  1  0  1  1  1  0  1  1  1  0  1  1  1 ];
N=length(s);
n = log2(N);

mask = zeros(1,N);
pattern1_indices = [];
pattern2_indices = [];
pattern3_indices = [];


for l= n:-1:1
    L = 2^l;
    t  = 2^(n-l); % Number of strings of size L

    pattern1= zeros(1,L);
    pattern3= pattern1;
    pattern3(end) = 1;
    pattern2 = ones(1,L);

    for i = 1:t
        st = (i-1)*L+1 ;
        ed = i*L ; 
        if(mask(st)==1)
            continue
        end
        chunk =  s(st:ed) ;

        if chunk == pattern3 % Only the last bit is one
            mask(st:ed) = 1;
            pattern3_indices = [pattern3_indices ; [st,ed]];
        elseif chunk == pattern1
            mask(st:ed) = 1; % All zero
            pattern1_indices = [pattern1_indices ; [st,ed]];
        elseif chunk == pattern2
            mask(st:ed) = 1; % All one
            pattern2_indices = [pattern2_indices ; [st,ed]];
        end         
    end
end

我得到每个模式的开始和结束索引如下,

pattern1_indices

pattern1_indices =

     []

>> pattern2_indices

pattern2_indices =

    15    16
    23    24
    27    28
    31    32

>> pattern3_indices

pattern3_indices =

     1     4
     5     8
     9    12
    17    20
    13    14
    21    22
    25    26
    29    30

【讨论】:

    【解决方案2】:

    我想最简单的解决方案是使用regular expressionregexp

    %binary string example
    s = '0000000111110000'
    
    %Get the start Index (SI) and the end Index (EI)
    [SI,EI] = regexp(s,'0+$')       %pattern 1
    [SI,EI] = regexp(s,'0+1')       %pattern 2
    [SI,EI] = regexp(s,'(?<!0)1+')  %pattern 3
    

    注意到 matlab 上的索引以 1 而不是 0 开头。

    你也可以一次使用多个正则表达式:

    [SI,EI] = regexp(s,{'0+$','0+1','(?<!0)1+'})
    

    结果:

    SI = 
    {
      [1,1] =  13
      [1,2] =  1
      [1,3] =  9
    }
    EI = 
    {
      [1,1] =  16
      [1,2] =  8
      [1,3] =  12
    }
    

    【讨论】:

    • 这不包括子串的位置要求。
    • @CrisLuengo 我没有得到你的评论,你能详细说明一下吗?
    • OP 要求子字符串占据字符串的二叉树表示中的完整分支。因此,2 元素子字符串必须从 1、3、5 等开始。4 元素子字符串必须从 1、4、8 等开始。你不能有 3 元素子字符串。或者至少我是这样解释的。 :)
    • 好吧,谢谢,我现在明白了 :) 是的,好吧,你是对的,我错过了。我要编辑我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-28
    • 2010-11-20
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 2019-09-06
    • 2019-06-18
    相关资源
    最近更新 更多