【问题标题】:String comparison on cell array of strings with Matlab Coder使用 Matlab Coder 对字符串元胞数组进行字符串比较
【发布时间】:2026-01-24 13:05:02
【问题描述】:

我正在尝试使用 MATLAB Coder 工具箱将以下代码转换为 C:

function [idx] = list_iterator(compare, list)

idx = nan(length(list));
for j = 1:length(list)
    idx(j) = strcmp(compare, list{j});
end

list 是一个 N x 1 的字符串元胞数组,compare 是一个字符串。该代码基本上将list 的每个元素与compare 进行比较,如果两者相同则返回1,否则返回0。 (我这样做是为了加快执行速度,因为 N 可能非常大 - 大约 10 到 2000 万个元素。)

当我在命令行窗口中运行codegen list_iterator 时,出现以下错误:

函数“list_iterator”的输入参数“比较”的类型 未指定。使用 -args 或预处理语句来指定 输入类型。

更多信息

==> list_iterator 行中的错误:1 栏目:18

代码生成失败:查看错误报告

使用代码生成时出错

我知道在使用codegen 时我应该指定输入的类型,但我不确定如何为字符串元胞数组执行此操作,其中的元素可以具有不同的长度。字符串compare 也可以有不同的长度,具体取决于函数调用。

【问题讨论】:

    标签: matlab code-generation string-comparison matlab-coder


    【解决方案1】:

    您可以使用函数coder.typeof 来指定codegen 的可变大小输入。根据我对您的示例的理解,类似于:

    >> compare = coder.typeof('a',[1,Inf])
    
    compare = 
    
    coder.PrimitiveType
       1×:inf char
    >> list = coder.typeof({compare}, [Inf,1])
    
    list = 
    
    coder.CellType
       :inf×1 homogeneous cell 
          base: 1×:inf char
    >> codegen list_iterator.m -args {compare, list}
    

    似乎合适。

    如果您查看 MATLAB Coder App,它提供了一种指定这些复杂输入的图形方式。从那里您可以将其导出到构建脚本以查看相应的命令行 API:

    https://www.mathworks.com/help/coder/ug/generate-a-matlab-script-to-build-a-project.html?searchHighlight=build%20script&s_tid=doc_srchtitle

    请注意,当我使用 codegen 尝试此示例时,生成的 MEX 并不比 MATLAB 快。发生这种情况的原因之一是函数的主体相当简单,但是大量数据从 MATLAB 传输到生成的代码并返回。因此,这种数据传输开销会支配执行时间。将更多代码移至生成的 MEX 可能会改善这一点。

    考虑与codegen 无关的性能,您应该使用idx = false(length(list),1); 而不是idx = nan(length(list));?前者是Nx1逻辑向量,后者是NxN双矩阵,我们只写list_iterator的第一列。

    使用您的原始代码和输入 compare = 'abcd'; list = repmat({'abcd';'a';'b'},1000,1); 这给了时间:

    >> timeit(@()list_iterator(compareIn, listIn))
    
    ans =
    
        0.0257
    

    修改您的代码以返回一个向量会缩小:

    function [idx] = list_iterator(compare, list)
    
    idx = false(length(list),1);
    for j = 1:length(list)
        idx(j) = strcmp(compare, list{j});
    end
    
    >> timeit(@()list_iterator(compareIn, listIn))
    
    ans =
    
        0.0014
    

    您还可以使用单元格和字符数组调用strcmp,这样可以使代码更快:

    function [idx] = list_iterator(compare, list)
    
    idx = strcmp(compare, list);
    
    >> timeit(@()list_iterator(compareIn, listIn))
    
    ans =
    
       2.1695e-05
    

    【讨论】:

      最近更新 更多