У меня есть двоичная строка длины 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?
2 ответа
Я реализовал решение рекурсивно, как показано ниже,
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
Я предполагаю, что наиболее простым решением будет использование регулярного выражения с regexp
%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
}
Новые вопросы
matlab
MATLAB - это высокоуровневая языковая и интерактивная среда программирования для численных расчетов и визуализации, разработанная MathWorks. Не используйте оба тега [matlab] и [octave], если явно не задан вопрос о сходстве или различии между ними. При использовании этого тега, пожалуйста, укажите версию MATLAB, с которой вы работаете (например, R2017a).