2013-12-13 5 views
-2

Я ищу эффективный алгоритм поиска слов. Если вы можете помочь мне придумать это, было бы еще лучшеалгоритм поиска слов matlab

a h c k 
x r j i 
b v t l 
c y q s 

и я хочу найти «искусство». Если «stra» также было правильным словом, я хочу, чтобы это тоже было найдено. (вертикальный, горизонтальный, диагональный и обратный). Я придумал несколько алгоритмов, но вы не выглядите эффективными и потребляете длинное кодирование. Во-первых, с помощью find(), чтобы получить первую букву и посмотреть на этот столбец или строки.

+2

Покажите, что вы пробовали до сих пор. – Hanady

+3

Это университетское задание, не так ли? Двое из ваших коллег были здесь раньше. Сначала прочитайте [здесь] (http://stackoverflow.com/questions/20406257/does-matlab-have-a-function-similar-to-strfind/20406898#20406898), затем [здесь] (http: // stackoverflow. com/questions/20380587/is-it-possible-to-rotate-a-matrix-by-45-degrees-in-matlab/20381889 # 20381889) и, наконец, [здесь] (http://stackoverflow.com/questions/ 20334461/Wordsearch-алгоритм-в-MATLAB). Если у вас все еще есть вопросы, сообщите нам, где именно вы застряли. – thewaywewalk

+0

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

ответ

4

Вот один из способов:

%// Example word grid 
C = [ 
    'a' 'h' 'c' 'k' 'r' 
    'x' 'r' 'j' 'i' 'p' 
    'b' 'v' 't' 'l' 'q' 
    'a' 'y' 'q' 's' 'o']; 

%// Your search term 
target = 'arts'; 

%// Optionally, do some obvious checks here. 
%// - length of the search string may exceeds the grid's dimensions 
%// - there are no matches for the first letter 
%// - and similar 

%// Form single cellstring containing all search directions 
allDirections = [ 
    %{ 
    // horizontal, horizontal-reversed 
    %} 
    cellstr([C ; C(:,end:-1:1)]) 
    %{ 
    // vertical, vertical-reversed 
    %} 
    cellstr([C'; C(:,end:-1:1)']) 
    %{ 
    // Diagonal, top-left to bottom-right, and reversed 
    %} 
    arrayfun(@(ii){diag(C,ii)'}, -size(C,1)+2:size(C,2)-2)'; 
    arrayfun(@(ii){diag(C(end:-1:1,end:-1:1),ii)'}, -size(C,1)+2:size(C,2)-2)'; 
    %{ 
    // Diagonal, top-right to bottom-left, and reversed 
    %} 
    arrayfun(@(ii){diag(C(:,end:-1:1),ii)'}, -size(C,1)+2:size(C,2)-2)'; 
    arrayfun(@(ii){diag(C(end:-1:1,:),ii)'}, -size(C,1)+2:size(C,2)-2)'; 
]; 

%// And now just find the string 
strfind(allDirections , target) 

Конечно, вы могли бы улучшить (память) эффективность по

  • делает strfind по всем направлениям отдельно
  • делать 2 × strfind на в том же направлении, но с target перевернутым
  • и т.д.

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

Теоретически более эффективный рекурсивный, ветвей и границ тип поиска примерно выглядит следующим образом:

  • найти все вхождения первой буквы
  • устранения всех этих явлений, которые не могут удовлетворить длину из target на основе размеров сетки
  • Поиск окрестностей всех хитов вхождений второго письма
  • искоренению вхождений на основе длины и т.д.

(Не забудьте фильтровать по направлению после второго письма, как хиты для второй буквы фиксирует направление поиска)

Насколько я понимаю, это нужно было бы намного меньше читает и сравнивает, чем моя версия. Тем не менее, я предполагаю, что использование законченных процедур (как и я) будет более быстрым и менее сложным, чем использование (вложенных) циклов. Но я могу ошибаться.

Попробуйте. Профиль. Учить. Улыбка. Исправьте меня :)

+0

приятный подход! но, вероятно, трудно сказать, где именно слово начиналось в исходной матрице, не так ли? И насколько я знаю из подобных вопросов, возможно, что одно слово появляется несколько раз. А также, поскольку вы просто конкатенируете все, что происходит, если есть «неверное» слово над двумя строками, такими как: C = [a r; t s]; он будет обнаружен вашим алгоритмом, но неверен. Я прав? – thewaywewalk

+0

@thewaywewalk: (а) это правда, хотя довольно легко получить, где произошел удар (ы), так как вы знаете, какая строка в 'allDirections' соответствует тому, что строка/col/direction. (b) Нет. Я конкатенирую целые строки символов, а не отдельные символы. Просто напечатайте 'allDirections', чтобы понять, что я имею в виду. Каждая запись в этой ячейке является допустимой строкой, соответствующей правилам OP. –

Смежные вопросы