【问题标题】:convert from double to strings从双精度转换为字符串
【发布时间】:2016-04-20 14:17:45
【问题描述】:

我有双A的矩阵

  A=[1 1 1 2 1;
     2 1 1 2 1;
     3 1 1 2 1;
     4 1 1 2 1;
     1 2 1 2 1;
     2 2 1 2 1;
     3 2 1 2 1;
     4 2 1 2 1];

我想将其转换为字符串矩阵B

B= {'11121';
    '21121';
    '31121';
    '41121';
    '12121';
    '22121';
    '32121';
    '42121'}.

为此,我尝试使用num2str,但我得到C,每个字符串内部都有两个空格

C = {'1  1  1  2  1';
     '2  1  1  2  1';
     '3  1  1  2  1';
     '4  1  1  2  1';
     '1  2  1  2  1';
     '2  2  1  2  1';
     '3  2  1  2  1';
     '4  2  1  2  1'} 

我不知道如何删除C 中的空格。

【问题讨论】:

  • 我添加了这条评论,因为其他答案可能更好,但您可以轻松删除 C 中的所有空格,如下所示:cellfun(@(s)s(s~=' '), C)
  • @elis56 - 只是想知道 - 你说输入矩阵是double,但在你的例子中它包含一位整数。可能输入的实际值是多少?会有分数,复数等吗?还是它们总是代表个位数的正整数?
  • 如果你的字符串长度都一样,你为什么要一个元胞数组?普通的 char 矩阵可能会更快。

标签: string matlab double


【解决方案1】:

一种方法是使用sprintf 将数组转换为一长串数字。然后,您可以将此字符串重塑为适当的形状。然后您可以使用cellstr 将重整后的字符串的每一行转换为单独的元胞数组元素。

out = cellstr(reshape(sprintf('%d', A), [], size(A,2)));

说明

先将矩阵转换成一长串数字。

s = sprintf('%d', A)
%// 1234123411112222111111112222222211111111 

然后我们要对其进行重塑,使原始中的每一行数字都是输出中的一行数字

s = reshape(s, [], size(A,2))
%// 11121
%// 21121
%// 31121
%// 41121
%// 12121
%// 22121
%// 32121
%// 42121

然后我们可以使用cellstr 将每一行 this 转换成它自己的单元格数组

out = cellstr(s);
%// '11121'
%// '21121'
%// '31121'
%// '41121'
%// '12121'
%// '22121'
%// '32121'
%// '42121'

另一种方法

实现此目的的另一种方法是将A 的每一列视为一个位置值(即 10000 的位置、1000 的位置、100 的位置等)并将每一行转换为知道这一点的整数。这可以通过将每一行与10^(N-1:-1:0) 的数组相乘并对元素求和来轻松完成。这将为组合所有列的每一行产生一个数字。然后我们可以使用num2str 将其转换为字符串元胞数组。

%// Then convert each number to a string in a cell array
out = arrayfun(@num2str, A * (10.^(size(A, 2)-1:-1:0)).', 'uni', 0);

或者更短一点,我们可以从@rayryeng's 书中借一页并使用sprintfc 将此整数数组转换为字符串元胞数组:

out = sprintfc('%d', A * (10.^(size(A, 2)-1:-1:0)).');

基准测试

我很好奇这里和@rayryeng's answerDev-iL's answer 中介绍的方法在增加行数时的性能。我写了一个快速测试脚本。

function tests()
    % Test the number of rows between 100 and 10000
    nRows = round(linspace(100, 10000, 100));

    times1 = zeros(numel(nRows), 1);
    times2 = zeros(numel(nRows), 1);
    times3 = zeros(numel(nRows), 1);
    times4 = zeros(numel(nRows), 1);
    times5 = zeros(numel(nRows), 1);

    %// Generate a random matrix of N x 5
    getRandom = @(n)randi([0, 9], [n, 5]);

    for k = 1:numel(nRows)
        A = getRandom(nRows(k));
        times1(k) = timeit(@()string_reshape_method(A));
        A = getRandom(nRows(k));
        times2(k) = timeit(@()base10_method(A));
        A = getRandom(nRows(k));
        times3(k) = timeit(@()sprintfc_method(A));
        A = getRandom(nRows(k));
        times4(k) = timeit(@()addition_method(A));
    end

    %// Plot the results
    plot(nRows, cat(2, times1, times2, times3, times4)*1000);
    legend({'String Reshape', 'Base-10 Conversion', 'sprintfc', 'addition of "0"'})

    xlabel('Number of Rows in A')
    ylabel('Execution Time (ms)');
end

function out = string_reshape_method(A)
    out = cellstr(reshape(sprintf('%d', A), [], size(A,2)));
end

function out = base10_method(A)
    out = sprintfc('%d', A * (10.^(size(A, 2)-1:-1:0)).');
end

function B = sprintfc_method(A)
    B = sprintfc(repmat('%d', 1, size(A,2)), A);
end

function B = addition_method(A)
    B = cellstr(char(A + '0'));
end

这是结果。

【讨论】:

  • @elis56 如果您对不同方法的性能感兴趣,请务必查看更新后的帖子。
  • 我现在看到了这个帖子:非常感谢情节和建议:)
【解决方案2】:

我的建议是这样的:

out = cellstr(char(A + '0'));

基本上我们所做的是将0 的ASCII 值添加到您的矩阵中,然后将其转换为字符。我没有对其进行基准测试,但它应该相当快:)

【讨论】:

  • 这仅适用于小于9 的数字
  • @Dan - 感谢您指出这一点。我太专注于提供的示例...
  • @Dev-iL 我认为这是一个公平的假设,并且公认的reshape 方法可能也有这个限制
【解决方案3】:

使用未记录的东西怎么样?我们可以看到每个单元格有 5 个数字,或者每个单元格的总列数。因此,为fprintf%d 创建一个格式字符串,但复制的列与A 中的列一样多,然后使用未记录的函数sprintfc 将数字转换为一次拍摄细胞:

s = repmat('%d', 1, size(A,2));
B = sprintfc(s, A);

示例运行

>> A=[1 1 1 2 1;2 1 1 2 1;3 1 1 2 1;4 1 1 2 1;1 2 1 2 1;2 2 1 2 1;3 2 1 2 1;4 2 1 2 1];
>> s = repmat('%d', 1, size(A,2));
>> B = sprintfc(s, A)

B = 

    '11121'
    '21121'
    '31121'
    '41121'
    '12121'
    '22121'
    '32121'
    '42121'

【讨论】:

  • @Suever Hehe... 因此它值得被称为未记录的函数:D。谢谢。
【解决方案4】:

基于num2str 输出中“清除空格”的方法:

方法一:

cellfun(@(s)s(s~=' '), num2str(A));

方法二:

regexprep(cellstr(num2str(A)),' ','');

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-11
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多