Переупорядочивание массива ячеек, содержащего строки

введите здесь описание изображения

Содержимое массива ячеек такое же, как на изображении выше. У меня есть две проблемы:

  1. Мне нужно переместить ячейки в столбцах на предыдущие, где есть 0s. Например, в row 1 ячейка 1x7 должна прийти к ячейке после 1x19 ячейки и так далее.

  2. При этом ячейки с [] также должны быть перемещены, заменив предшествующие 0s.

Я пытался использовать strncmp, ismember и другие функции, но 0 выдает ошибки.

ОБНОВИТЬ с рабочим кодом

Код такой:

Однако он не выполняет всю работу. Копируемые ячейки должны быть удалены с конца.

for m=1:200
for i=1:46
    for j=1:199

        try
            if(tags{i,j}==0)
                for k=j:199
                    tags{i,k}=tags{i,k+1};
                    tags{i,k+1}='';
                end
            end
        catch exception

        end
    end
end
end

EDIT – Часть 2 вопроса: еще не решена

Каждая из ячеек содержит строки. Есть ли способ записать их в текстовый файл? Все строки в ячейке должны быть в одной строке, за которой следует новая строка для строк в следующей ячейке.

Опять же, я пробовал это, используя множество функций, но я не могу сделать это правильно. Я просто получаю первую строку в каждой ячейке в текстовый файл.


person Sharath Chandra    schedule 27.05.2014    source источник
comment
Но тогда у вас разное количество элементов в каждой строке/столбце? Как вы хотите справиться с этим? Заполнить []?   -  person thewaywewalk    schedule 27.05.2014
comment
да. Концы можно заполнить [].   -  person Sharath Chandra    schedule 27.05.2014
comment
Вы можете записать в своем примере ячейку 1x7 в первую ячейку 0? И единственная проблема заключается в удалении 0? или у вас тоже проблемы с письмом? Не могли бы вы опубликовать свой код, который у вас есть до сих пор?   -  person The Minion    schedule 27.05.2014
comment
Я предлагаю вам создать массив t/f со значением true везде, где нет нуля, затем создать новый массив со всеми [] и для каждой строки заполнить столбцы 1:n ненулевыми элементами.   -  person Jonas    schedule 27.05.2014
comment
@Jonas На самом деле у меня есть логическая переменная t/f с этой информацией. Используя это, я обнулил несуществующие ячейки из матрицы - я не мог понять, как заполнить столбцы с ненулевой ячейкой записей ячеек для каждой строки.   -  person Sharath Chandra    schedule 28.05.2014


Ответы (2)


Вот альтернативный подход: вместо того, чтобы перебирать массив, создайте новый и заполните только ненулевые значения (примечание: если вы хотите избежать создания нового массива, вы можете в цикле создать временную копию строку, очистить строку в массиве и перезаписать). Кстати, с некоторым умным перетасовкой массива вы можете выполнить шаг 3 без цикла.

%# step 1: find non-zeros
nonZeros = cellfun(@(x) ~iscell(x) && ~isempty(x), tags);

%# step 2: create new array with all empty
[nRows,nCols] = size(tags);
newTags = cell(nRows,nCols);

%# step 3: for every row: copy the non-zero entries
[goodRows,goodCols] = find(nonZeros);

for iRow = 1:nCols;
    myGoodCols = goodCols(goodRows==iRow);
    nGoodCols = length(myGoodCols);
    if nGoodCols > 0 && nGoodCols < nCols
       %# shift everything
       newTags(iRow, 1:nGoodCols) = tags(iRow,myGoodCols);
    end
end

%# step 4 : write out tags
fid = fopen('tags.txt','w+');
for iRow = 1:nRows
    for iCol = 1:nCols
        if ~isempty(tags{iRow,iCol})
        fprintf(fid,'row %i col%i : ',iRow,iCol);
        fprintf(fid,'%s ',tags{iRow,iCol}{:});
        fprintf(fid,'\n');
        end
    end
end
person Jonas    schedule 28.05.2014

Редактировать 2
Думаю, проблема в том, что ваши нули были не числами, а строками или символами. В этом случае просто замените if-аргументы преобразованием из ячейки в матрицу cell2mat, как показано в следующем коде. Надеюсь, это решит вашу проблему.

Если нет, не могли бы вы опубликовать строки кода, которые вы использовали для создания нулей и других элементов?

for k=1:200 %For looping on all columns 
    for i=1:46 %For  max rows
    try     
        if cell2mat(test_mat(1,i))== '0'
            test_mat{1,i}='';
            for j=i:46 % For max columns
              try
                if cell2mat(test_mat(1,j))~='0' 
                    test_mat{1,i}=test_mat{1,j};
                    test_mat{1,j}='';
                    break
                end
                catch exception
              end
            end

        end
    catch exception
    end
    end
end

Изменить 1

 for k=1:200 %For looping on all columns 
    for i=1:46 %For  max rows
    try
        if test_mat{k,i}==0
            test_mat{k,i}='';
            for j=i:46 % For max columns
              try
                if test_mat{k,j}~=0 
                    test_mat{k,i}=test_mat{k,j};
                    test_mat{k,j}='';
                    break
                end
                catch exception
              end
            end
        end
    catch exception
    end
    end
 end

Эй, это должно знать, замените ваши элементы правильно.
старый ответ Эй, не уверен в одном. Но это должно работать

for k=1:max_row
   try
      if cell2mat(test_mat(1,k)) ==0 
         for j=k:max_row
           if cell2mat(test_mat(1,j)) ~= 0
               test_mat(1,k) = test_mat(1,j);
               test_mat(1,j) = {''};
               break
           end
         end
      end
      catch exception
   end
end

Здесь я зацикливаюсь только на первой строке (для всех строк вы можете добавить еще один цикл, включая этот код). Первый if проверяет, равен ли элемент 0. Если да, то второй if проверяет ненулевой элемент в той же строке, но в более позднем столбце. Затем я записываю этот элемент на место 0 и заменяю его на [].
Я не уверен, что это эффективное решение в отношении времени выполнения.
И что я не уверен, так это ваша 7-я строка. Что там должно произойти? Перемещается ли 3 ненулевой элемент <1x7>cell на место <1x11>cell, остается там, где он есть, или возвращается на один слот назад?

person The Minion    schedule 27.05.2014
comment
В 7-й строке 0 можно сделать пустым. Но ваш код выдает эту ошибку: Ошибка при использовании cell2mat (строка 53) Невозможно поддерживать массивы ячеек, содержащие массивы ячеек или объекты. Ошибка в перемещении нулей (строка 18), если cell2mat(test_mat(1,k)) ==0 - person Sharath Chandra; 27.05.2014
comment
Ах, мой код работает только для матриц, которые заполнены числами, а затем преобразованы в ячейки, чтобы вы могли хранить данные разного размера в одной структуре. Какие данные находятся внутри ваших ячеек? - person The Minion; 27.05.2014
comment
Струны. Вот почему я поднял этот вопрос. В остальном было легко. - person Sharath Chandra; 27.05.2014
comment
@SharathChandra Эй, кажется, я исправил свой ответ. Было бы неплохо, если бы вы могли протестировать его. Один момент, который я не пробовал, - это то, что произойдет, если последним элементом столбца будет 0, и что произойдет, если нет кода для замены 0 на - person The Minion; 27.05.2014
comment
@SharathChandra Я снова изменил код. Теперь он заменяет все 0 на [], если в столбце больше нет ненулевого элемента. - person The Minion; 27.05.2014
comment
Это не работает - некоторые 0 заменяются на [], но движения не видно! - person Sharath Chandra; 28.05.2014
comment
@SharathChandra Я сделал еще одно редактирование. Возможно, проблема заключалась в том, что мои нули оставались числами. Вы можете попробовать новый код. Если это не работает, пожалуйста, опубликуйте код, который вы используете для создания своих элементов. - person The Minion; 28.05.2014
comment
Собственно проблема решена, выложил код в обновлении. Не могли бы вы помочь мне решить вторую задачу? - person Sharath Chandra; 28.05.2014