根据索引和值从数组元素创建结构

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了根据索引和值从数组元素创建结构相关的知识,希望对你有一定的参考价值。

是否有更优雅的方式来表达以下代码(例如,没有明确的for循环)?

P = [0.1 0.2 0.3 0.4];
% pre-allocate symbols array of struct
symbols = repmat(struct('probability', 0, 'indices', []), length(P), 1);
for i =1:length(P)
   symbols(i) = struct('probability', P(i), 'indices', i); 
end

P.S。:如果有兴趣的话,我正在使用符号来实现霍夫曼编码。

编辑:受其中一条评论的启发,我可能最终会这样做

P = [0.1 0.2 0.3 0.4];
symbols = [
    [0.1 1];
    [0.2 2];
    [0.3 3];
    [0.4 4];
];
% access probability:
symbols(i)(1)
% access indices:
symbols(i)(2:end)

所以

symbols = [P(:) (1:length(P))']

Edit2:为了完整性,这里是我正在使用的整个代码(霍夫曼代码)

function [c,h,w]=huffman(P)

assert(abs(sum(P) - 1) < 10e-6, "Probabilities must sum up to 100%");

% compute entropy
h = sum(P .* (-log2(P)));
% each row corresponds to the probability in P
c = cell(length(P), 1); % codes are represent as numerical vectors for bits

P = sort(P, 'descend');
% Preallocate 'symbols' for each probability
% A symbol is used to represent dummy "fused" probabilities as well
% size(symbols) == 1xlength(P) initially
% IMPORTANT: sort P first descending
symbols = struct('probability', num2cell(P), 'indices', num2cell(1:length(P)));
%symbols = repmat(struct('probability', 0, 'indices', []), length(P), 1);
%for i =1:length(P)
%   symbols(i) = struct('probability', P(i), 'indices', i); 
%end

while length(symbols) > 1
    % select the two lowest probabilities and add them
    % O(n) insert worst case vs log(n) binary search...
    last = symbols(end);
    preLast = symbols(end-1);
    % Build the code words by prepending bits
    c(last.indices) = cellfun(@(x)[0 x], c(last.indices), 'UniformOutput', false);
    c(preLast.indices) = cellfun(@(x)[1 x], c(preLast.indices), 'UniformOutput', false);
    % Insert dummy symbol representing combined probability of the two
    % lowest probabilities
    probSum = last.probability + preLast.probability;
    newSymbol = struct('probability', probSum, 'indices', [last.indices preLast.indices]);
    pos = find([symbols.probability] < probSum, 1);
    % insert dummy symbol and remove the two symbols which belong to it
    symbols = [symbols(1:pos-1) newSymbol symbols(pos:end-2)];
end
assert(length(symbols) == 1 && abs(symbols(1).probability - 1) < 10e-6, "Probability of tree root must add up to 100%");
% compute average codeword length
w = sum(cellfun('length', c) .* P(:));

我认为使用数值数组而不是结构并将0存储为“无索引”是更多的工作,因为我必须确保所有索引数组都使用零填充正确并在使用它们之前调用find(indices> 0)。所以我现在就跳过这个。

这大约是我在互联网上发现的一些random code的3倍,所以它不会很糟糕。

编辑3:事实上,它比通信系统工具箱中的犹太人大约快40%,所以你去吧。要么我缺少某些东西,要么他们不关心性能。

答案

怎么样:

symbols = struct('probability', num2cell(P), 'indices', num2cell(1:length(P)));

或(仅限八度,不是MATLAB):

symbols = repmat(struct('probability', 0, 'indices', []), length(P), 1);
[symbols.probability] = num2cell(P){:};
[symbols.indices] = num2cell(1:length(P)){:};

以上是关于根据索引和值从数组元素创建结构的主要内容,如果未能解决你的问题,请参考以下文章

数据结构:使用面向对象模拟数组

提取数组中非 NaN 元素的索引和值的正确方法

swift 使用enumerate()访问数组元素的索引和值

如何对包含空元素的对象数组进行排序?

根据值从多维数组中删除元素

将 numpy 数组类型和值从 Float64 转换为 Float32