Учитывая массив символов и вложенных строк, чтобы найти по горизонтали, вертикали, и оба диагональных направлениях:
A = char(randi(16,7,10)+'a'-1)
A =
ilhpcdchkl
ooaecloocd
kogajcdkpg
imlnnbiihf
bigoahciin
afjfjdhgmp
pejcdfnmke
% horizontal string in row 4, starting at col 5
cH = [4 5]; l = 4; % strings of length 4
sh = A(cH(1),cH(2)+(0:l-1))
sh =
nbii
% vertical string in col 6, starting at row 3
cV = [2 6];
sv = A(cV(1)+(0:l-1),cV(2)).' %'
sv =
lcbh
% diagonal (downward) string starting at row 3, col 7
cD = [3 7];
sd = A((cD(1)+(0:l-1))+size(A,1)*((cD(2)+(0:l-1))-1))
sd =
diip
% diagonal (upward) string starting at row 5, col 2
cU = [5 2]
su = A((cU(1)-(0:l-1))+size(A,1)*((cU(2)+(0:l-1))-1))
su =
ilac
Start с функцией, которая может искать строки матрицы для строки:
function ij = strsearch(A,s)
C = mat2cell(A,ones(size(A,1),1),size(A,2));
matches = strfind(C,s);
rows = find(~cellfun(@isempty,matches));
if ~isempty(rows),
cols = vertcat(matches{rows});
else
cols = [];
end
ij = [rows cols];
Например, это дает это (строка, столбец) расположение горизонтальной строки sh
в матрице A
:
>> ij = strsearch(A,sh)
ij =
4 5
Это отлично подходит для горизонтальных струн, но мы хотим, чтобы поиск во всех направлениях и направлениях. Мы новая функция, называем его wordsearch
, что будет выводить следующее:
>> matches = wordsearch(A,sh)
matches =
start: [4 5]
orientation: 'horizontal'
direction: 0 % forward
>> matches = wordsearch(A,sv)
matches =
start: [2 6]
orientation: 'vertical'
direction: 0
>> matches = wordsearch(A,sd)
matches =
start: [3 7]
orientation: 'downward diagonal'
direction: 0
>> matches = wordsearch(A,su)
matches =
start: [5 2]
orientation: 'upward diagonal'
direction: 0
>> matches = wordsearch(A,fliplr(sh))
matches =
start: [4 8] % sh goes from column 5 to 8, in row 4
orientation: 'h'
direction: 1 % backward
Чтобы получить это, мы можем построить на strsearch
для поиска горизонтальных и вертикальных вхождений перестановки матрицы. Обратные вхождения можно найти, перевернув входную строку. Для поиска диагоналей мы можем использовать arrayfun
и diag
, чтобы извлечь диагонали и выполнить поиск аналогичным образом.
Общая функция поиска:
function ij = wordsearcher(A,s,orientation,order)
s = s(:).'; %' ensure row vector
if order, s = fliplr(s); end
switch lower(orientation(1))
case 'h'
ij = strsearch(A,s);
if order && ~isempty(ij), ij(:,2) = ij(:,2) + numel(s) - 1; end
case 'v'
ij = fliplr(strsearch(A.',s)); %'
if order && ~isempty(ij), ij(:,1) = ij(:,1) + numel(s) - 1; end
case 'd' % down-right diagonals
Cdiags = arrayfun(@(k)diag(A,k).',-size(A,1)+1:size(A,2)-1,'uni',0); %'
matches = strfind(Cdiags,s);
k = find(~cellfun(@isempty,matches));
if isempty(k), ij=[]; return; end
row = (k<=size(A,1)) .* (size(A,1) - k) + [matches{k}];
col = ~(k<=size(A,1)) .* (k - size(A,1)) + [matches{k}];
ij = [row; col].'; %'
if order, ij = ij+numel(s)-1; end
case 'u' % up-right diagonals
Cdiags = arrayfun(@(k)diag(flipud(A),k).', ... %' flip A up-down
-size(A,1)+1:size(A,2)-1,'uni',0);
matches = strfind(Cdiags,s);
k = find(~cellfun(@isempty,matches));
if isempty(k), ij=[]; return; end
row = ~(k<=size(A,1)) .* (size(A,1) - k) + k - [matches{k}] + 1;
col = ~(k<=size(A,1)) .* (k - size(A,1)) + [matches{k}];
ij = [row; col].'; %'
if order, ij=bsxfun(@plus,ij,numel(s)*[-1 1]); end
otherwise
error('bad orientation')
end
Wrap, что с петлями для поиска во всех направлениях/направлениях, чтобы получить wordsearch
функцию:
function matches = wordsearch(A,s)
matches = struct('start',[],'orientation',[],'direction',[]);
n=1; o='hvdu';
ostr = {'horizontal','vertical','downward diagonal','upward diagonal'};
for id=0:1,
for io=1:numel(o),
ij = wordsearcher(A,s,o(io),id);
if ~isempty(ij),
matches(n).start = ij;
matches(n).orientation = ostr{io};
matches(n).direction = id;
n = n+1;
end
end
end
Я надеюсь, что это работает.
'words (2)' typo? Что такое 'words (1)'? Вот еще один вопрос, связанный с подобной проблемой, но в настоящее время разрешает только строки и первую диагональ: http://stackoverflow.com/questions/20502065/matlab-loop-not-working – Daniel
@ user3058703 Я ценю, что вы подумали.Я взломал код, который обращается к задаче, но не так, как ваш описанный алгоритм. – chappjc