У меня есть матрица двойных 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.

2
elis56 20 Апр 2016 в 17:17

4 ответа

Лучший ответ

Один из способов сделать это - использовать 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 для преобразования каждой строки в собственный массив ячеек.

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 и использовать sprintfc для преобразования этот массив целых чисел в массив ячеек строк:

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

Контрольный показатель

Мне было интересно узнать о производительности методов, представленных здесь и в ответе @ rayryeng и Dev-iL 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

Вот результаты.

enter image description here

6
Community 23 Май 2017 в 10:28

Мое предложение таково:

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

В основном мы добавляем значение ASCII 0 в вашу матрицу, а затем преобразуем его в символы. Я не тестировал его, но он должен быть сравнительно быстрым :)

5
Dev-iL 20 Апр 2016 в 15:21

Как насчет использования чего-то недокументированного? Мы видим, что у вас есть 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'
4
rayryeng 20 Апр 2016 в 14:35

Методы, основанные на "очистке пробелов" из вывода num2str:

Метод 1:

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

Метод 2:

regexprep(cellstr(num2str(A)),' ','');
1
Dev-iL 8 Июн 2016 в 17:45