从双精度转换为字符串
convert from double to strings
我有双矩阵 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
中的空格。
执行此操作的一种方法是使用 sprintf
to convert the array to a long string of digits. You can then reshape this string into the appropriate shape. Then you can use 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
将每一行转换成它自己的元胞数组
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);
或者为了进一步缩短这个时间,我们可以借用 书中的一页并使用 sprintfc
将这个整数数组转换为字符串元胞数组:
out = sprintfc('%d', A * (10.^(size(A, 2)-1:-1:0)).');
基准
当您增加行数时,我很好奇这里和 and 中介绍的方法的性能。我写了一个快速测试脚本。
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
这是结果。
使用未记录的东西怎么样?我们可以看到每个单元格有 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'
我的建议是:
out = cellstr(char(A + '0'));
基本上我们所做的是将 0
的 ASCII 值添加到您的矩阵,然后将其转换为字符。我没有对它进行基准测试,但它应该相当快:)
基于 num2str
输出的 "clearing the spaces" 的方法:
方法一:
cellfun(@(s)s(s~=' '), num2str(A));
方法二:
regexprep(cellstr(num2str(A)),' ','');
我有双矩阵 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
中的空格。
执行此操作的一种方法是使用 sprintf
to convert the array to a long string of digits. You can then reshape this string into the appropriate shape. Then you can use 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
将每一行转换成它自己的元胞数组
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);
或者为了进一步缩短这个时间,我们可以借用 sprintfc
将这个整数数组转换为字符串元胞数组:
out = sprintfc('%d', A * (10.^(size(A, 2)-1:-1:0)).');
基准
当您增加行数时,我很好奇这里和
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
这是结果。
使用未记录的东西怎么样?我们可以看到每个单元格有 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'
我的建议是:
out = cellstr(char(A + '0'));
基本上我们所做的是将 0
的 ASCII 值添加到您的矩阵,然后将其转换为字符。我没有对它进行基准测试,但它应该相当快:)
基于 num2str
输出的 "clearing the spaces" 的方法:
方法一:
cellfun(@(s)s(s~=' '), num2str(A));
方法二:
regexprep(cellstr(num2str(A)),' ','');