【问题标题】:Solving a wordsearch puzzle in matlab在matlab中解决一个单词搜索难题
【发布时间】:2013-12-19 06:02:00
【问题描述】:

发布我的全部代码,希望有人可以帮助我调试这个废话。真的希望尽快得出结论,因为我已经玩这个太久了。

我这里有一个函数提取,它传递了一个整数网格,代表我的 wordsearch 函数中的字母(即 A=1,Z=26)。给定一个方向和一个由整数的行向量表示的目标单词,它应该遍历网格以找到第一个字母存在的位置,并从这里向所有方向移动以获取单词的长度并提取单词,例如如果我们正在寻找 [14, 5, 9, 2] 并且 14 首先定位在 (4,4) 我们应该最终定位在 (4,8)。

然后在搜索功能中比较该单词,如果它与目标单词匹配,则会在实际单词搜索的图像上从第一个字母到最后一个字母画一条线。

我知道我的 if 和 for 循环在某些地方是关闭的,但我发现很难更正我的代码以使其正常工作。帮助!特别是我遇到困难的一件事是控制流量,以便如果在检查包含第一个字母的正方形的所有方向之后,评估该字母的下一个实例。最好在哪里执行此操作?

代码有很多错误,可以通过几个指针告诉我它需要更改或清理的地方。

%//A function to find a word in a grid.
function test = extract(grid, direction, target) 

%//switch through different cases that allow us to move to any adjacent cell to the current    
switch upper(direction)
    case 1 
        rowdir = -1; 
        coldir = 0; 
    case 2 
        rowdir = -1; 
        coldir = 1; 
    case 3 
        rowdir = 0; 
        coldir = 1; 
    case 4 
        rowdir = 1; 
        coldir = 1; 
    case 5 
        rowdir = 1; 
        coldir = 0; 
    case 6 
        rowdir = 1; 
        coldir = -1; 
    case 7 
        rowdir = 0; 
        coldir = -1; 
    case 8 
        rowdir = -1; 
        coldir = -1;  
end

[i, j] = size(grid); 
len = length(target); 
[row,column] = find(target(1)==grid); %//find the letter of the word we are looking for in grid
%//row and column of last letter having moved in a particular direction
rowN = row + (len-1) * rowdir; 
colN = column + (len-1) * coldir; 

%//trying to say here to only move in a particular direction if we don't go out of bounds. 
%//not sure I've succeeded
if (rowN > 1) | (rowN < i) | (colN > 1) | (colN < j) 
     testword = []; %empty array created
    for index = 1:len 
        index_1 = index-1;
        %//on loop get the letter in adjacent cell for direction we have moved
        word = grid(row + (index_1 * rowdir), column + (index_1 * coldir)); 
        testword{index} = word; %//letters are appended to create word for which we compare.
        %//get co-ords of start letter. change to pixel  co-ordinates so we can evaluate on image
        wordstart = [(row*30)-15, (column*30)-15 ]; 
        wordend = [((row + (len-1 * rowdir))*30)-15, ((column + (len-1 * coldir))*30)-15];
    end 
else
    word = '';
end 

  x1 = wordstart(1);
  x2 = wordend(1);
  y1 = wordstart(2);
  y2 = wordend(2);

  test = [ word , [x1,x2] , [y1,y2]]; %//only way I could think of to get all of these as outputs

end

%//test is the image we want to evaluate on
%//words is the list of words

function trial1 = wordsearch(test, words)

imagesc(test);
colormap(gray);
hold on;

grid = %//grid is a 15x15 matrix

[row, column] = size(grid); 

for iword = 1 : length(words) 
    target = char(words(iword)) - 'a' + 1;
    for i = 1:row 
        for j = 1:column 
            for direction_num = 1:8 %//for each direction
                direction = directions(direction_num, :);
                testword = extract(grid,direction,target); 
                if testword(1)==target %//if word we have extracted equals the target word

%//draw_line function takes x co-ordinates and y co-ordinates and plots line.
                    draw_line(testword(2),testword(3),testword(4),testword(5)); 
                end
            end
        end
    end
end

hold off;
end

@丹

我的提取函数现在看起来像:

[i, j] = size(grid);
len = length(target); 
[row,column] = find(target(1)==grid);
for ii = 1:length(row)
    start_row = row(ii);
    start_column = column(ii); 
    rowN = start_row + len-1 * rowdir; 
    colN = start_column + len-1 * coldir; 
    if (rowN > 1) || (rowN < i) || (colN > 1) || (colN < j) 
        testword = [];
        for index = 1:len
        index_1 = index-1;
        word = grid(start_row + (index_1 * rowdir), start_column + (index_1 * coldir));
        testword{index} = word;
        wordstart = [(start_row*30)-15, (start_column*30)-15 ];
        wordend = [((start_row + (len-1 * rowdir))*30)-15, ((start_column + (len-1 * coldir))*30)-15];
        end 
    else

    end
end 

如果先前在那个特定方向上让你超出界限,我会用什么作为 else 语句来检查这个词?

【问题讨论】:

  • 获取所有输出的方法有很多,例如制作一个结构(test.word = word; test.x = [x1,x2]...)或者使用多个输出:function [word , X , Y]= extract(grid, direction, target),然后在你的函数末尾有X = [x1,x2]

标签: matlab octave


【解决方案1】:
for iword = 1 : length(words) 
    target = char(words(iword)) - 'a' + 1;
    for i = 1:row 
        for j = 1:column 
            for direction_num = 1:8 %//for each direction

对于每个单词,您都在遍历网格中的每个元素(即 ij 循环),但实际上您从未使用过这些 ij 值。所以这两个循环什么都不做!这是因为您似乎在 extract 函数中完成了所有这些操作。所以放弃这两个循环,它们浪费了大量的时间。

extract 函数中,有一行[row,column] = find...。这将找到 ALL 可能的起点。所以你实际上需要在某个地方循环遍历其中的任何一个。因此,我建议不要使用您的 if (rowN &gt; 1) | (rowN &lt; i) | (colN &gt; 1) | (colN &lt; j),而是建议:

for ii = 1:length(row)
    start_row = row(ii);
    start_column = column(ii); 
    %// And now re-use your code, but swap out all your row for start_row and your column for start_column
    .
    .
    .
end

这是遍历每个可能的起始字母的循环。

【讨论】:

  • 太好了,谢谢!我现在已经实现了这些更改,但是当我确信代码应该可以正常工作时,由于某种原因,我现在收到了越界错误。我不认为它每次都在尝试新的方向。列表中的第一个单词是“Barry”,我让它返回 B 在网格中的任何位置的坐标只是为了检查,但我得到了这个:尝试访问网格(0,4); index 必须是正整数或逻辑整数。提取错误(第 42 行) word = grid(start_row + (index_1 * rowdir), start_column + (index_1 * coldir));
  • @user3058703 但是是的,那是因为如果在边缘附近有 B,您仍然会将其与超出边缘的单词进行比较。我的建议是用非字母字符填充网格,例如 '*' 在所有边缘周围按最长单词的字符数
  • 那么提取函数的 for 循环中的 if 语句会阻止您在给定方向上搜索,如果朝那个方向移动会使您超出界限,所以我真正需要做的就是在 else 中说声明类似尝试下一个方向,但不确定这是怎么可能的。
  • @user3058703 for 函数的 for 循环内没有 if 语句。但是,如果您将if (rowN &gt; 1) | (rowN &lt; i) | (colN &gt; 1) | (colN &lt; j) 行留在其中(但现在将|s 更改为||s,因为您正在处理标量)然后它会为您检查边界并继续为您移动......?跨度>
  • 所以我期望发生的情况是,例如,如果在第 2 列和第 5 行找到第一个 B 并且单词是 'Barry',它不应该向北或向东北移动作为单词的长度* 这些方向的列方向小于 1,因此应尝试下一个方向。如果没有成功,则下一个,依此类推,直到所有都尝试过,在这种情况下,尝试下一个出现的字母。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-06
  • 2015-12-04
  • 1970-01-01
  • 2020-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多