如何在嵌入式Matlab中使用具有可变长度字符串的开关结构?

4
我从来不太喜欢嵌入式MATLAB,就是因为像我即将要问的情况:)在我的经验中,当你熟悉C语言和MATLAB API时,转换为嵌入式MATLAB往往需要更多的努力比重新用C语言编写。

但是,好吧,我想有些事情是无法避免的。

无论如何,这就是我的问题。在嵌入式MATLAB中(例如在R2010a中),你不能这样做:

for ii = <some range>

    parameter = <some string> 

    switch parameter

        case 'first_string'
            % do stuff

        case 'another_string_that''s_larger_than_first_string'
            % do other stuff
    end

    % ...continue here

end

在每次迭代中,<some string>都会发生变化。这是因为parameter字符串的长度是可变的,意味着此定义超出了嵌入式Matlab的能力范围:

??? 非常量表达式或空矩阵。此表达式必须是常量,因为它的值决定了某些表达式的大小或类。对于基于字符串的开关,只有常量字符串才受到限制,而不是数字。

switch改为更直接的形式

switch <some string> 
    ...
end

当然,这并没有帮助:
??? Expected a numeric value. Found a mxArray

即使将字符串的大小限制在已知的固定长度内,也无济于事:

parameter = char_array(ii, 1:4);  % <--- NOTE: length is 4 characters

switch parameter
    ...
end

但运气不佳:

??? 非常量表达式或空矩阵。此表达式必须是常量,因为它的值确定了某些表达式的大小或类。对于字符串开关,仅限于常量字符串,而不是数字开关。

我看到两种出路:

  1. 将所有可允许的字符串映射到某个数字表示,并在数字上使用开关
  2. 在巨大的 if-elseif-elseif-...-else-end 结构中使用 strcmp(i)

在我看来,这两种方法都同样丑陋,第二种可能更丑陋(你需要另一个外部函数 strcmp)...

那么,有没有任何 优雅 的方法可以解决这个问题?


我猜用空格填充字符串以使其长度相等会起作用?(虽然这不是你寻找的优雅解决方案。) - user1884905
@user1884905:不,我试过了...实际上,在我的真实函数中,前4个字符唯一确定了字符串,所以我尝试只使用前4个字符;没有运气,出现了相同的错误信息。 - Rody Oldenhuis
1个回答

1

很不幸,除了你提到的那些替代方法,我不知道还有其他方法。

更糟糕的是,MATLAB没有内置的字符数组到双精度标量哈希函数。因此,如果您想将字符串映射到数字,就需要提供自定义哈希函数。

就个人而言,我会选择您的第二种方法。它很丑陋,但易读。

既然您说只需考虑每个字符串的前4个字符,那么将字符串映射到数字的另一种选项是通过显式查找:

function y = fcn(u)
%#codegen

    y = u;

    cases = [
        '1111'
        '2222'
        '3333'
    ];

    for i = 1 : 3
        switch i
            case 1                
                p = '1111a';
            case 2
                p = '2222bb';
            otherwise
                p = '3333ccc';
        end      

        for j = 1 : size(cases, 1)
            if isequal(cases(j, 1 : 4), p)
                switch j
                    case 1
                        y = y + 1;
                    case 2
                        y = y + 2;
                    case 3
                        y = y + 3;
                end
            end
        end        
    end
end

在我看来,这并不容易阅读,如果你有大量的字符串需要处理,可能会浪费很多时间。你可以想出更高效的方法,但我仍然认为这是一种欺骗行为。

谢谢,这正是我担心的。我用了丑陋的 if-elseif-...-else-end 结构来解决它,我认为这确实是最可读的选择。将字符串映射到某些任意数字感觉有点像强制将大众甲壳虫送入低地球轨道……略微超出其设计限制 :) - Rody Oldenhuis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接