Structure Indexing to Find Words

2 ビュー (過去 30 日間)
Russell Marki
Russell Marki 2018 年 3 月 20 日
コメント済み: Russell Marki 2018 年 3 月 21 日
clear
load('dict_perms.mat')
dict=6;
dict_perms=dict_perms{6};
dict_char=char(dict_perms+64);
dict_size=length(dict_perms(:,1));
for i=1:dict_size
dict_lex.(dict_char(i,1)).(dict_char(i,2)).(dict_char(i,3)).(dict_char(i,4)).(dict_char(i,5)).(dict_char(i,6))=uint16(i);
end
%the next letters possible from a series of letters can be found with
letters=fieldnames(dict_lex.('A').('B').('H'));
%I want words from possible letters
%like dict_lex.(['A','B']).(['D','B']).(['F','H']).(['O','F']).(['R','M']).(['S','K'])
%could be found with a for loop but it is too time consuming
fieldnames(dict_lex.('A'));
fieldnames(dict_lex.('B'));
I need to find all possible words that have letters in certain parts of the word. This could be done with a for loop but that is too time consuming. Can anyone point me in the right direction?
  1 件のコメント
Stephen23
Stephen23 2018 年 3 月 21 日
"I need to find all possible words that have letters in certain parts of the word."
This is trivial with regular expressions. See my answer.

サインインしてコメントする。

採用された回答

Stephen23
Stephen23 2018 年 3 月 21 日
編集済み: Stephen23 2018 年 3 月 21 日
Dynamically accessing the fieldnames of nested structures is likely to be a very inefficient solution, and is far too complex for the task. You would be much better off simply accessing the data directly from the char array using logical indexing, or converting to a cell array of char vectors and then using standard, efficient built-in tools such as regular expressions, or even strncmp. For example:
>> DC = char(dict_perms{6}+64);
>> idx = DC(:,1)=='A' & DC(:,2)=='B' & DC(:,3)=='H';
>> DC(idx,:)
ans = ABHORS
To match multiple character you could add more logical conditions to the index:
>> idx = ...
(DC(:,1)=='A' | DC(:,1)=='B') & ...
(DC(:,2)=='B' | DC(:,2)=='D') & ...
(DC(:,3)=='H' | DC(:,3)=='F') & ...
(DC(:,4)=='O' | DC(:,4)=='F') & ...
(DC(:,5)=='R' | DC(:,5)=='M') & ...
(DC(:,6)=='S' | DC(:,6)=='K');
>> DC(idx,:)
ans = ABHORS
But actually it would be much easier and more versatile to use regular expressions:
>> DS = cellstr(DC);
>> idx = ~cellfun('isempty',regexp(DS,'^[AB][DB][FH][OF][RM][SK]','once'));
>> DC(idx,:)
ans = ABHORS
It is easy with regular expressions to return the complete matching words, the matching letters, their indices, or the trailing letters... it all depends on what you want. If you give a more accurate description of the data that you need then I can help you with the regular expression.
  2 件のコメント
Guillaume
Guillaume 2018 年 3 月 21 日
I agree with Stephen. This is exactly the sort of job regular expressions are designed for and it's unlikely you'll be able to write something more efficient. regular expression engines are highly optimised.
An alternative to storing the words as a 2d char array or a cell array of 1d char array would be to store them as a string array, which overall is a lot easier to manipulate. To convert the whole dict_perms in a cell array of string arrays:
dict_lex = cellfun(@(c) string(char(c+64)), dict_perms, 'UniformOutput', false)
Russell Marki
Russell Marki 2018 年 3 月 21 日
Thanks, this is exactly what I am looking for.

サインインしてコメントする。

その他の回答 (1 件)

KSSV
KSSV 2018 年 3 月 21 日
T = table(dict_char) ;
T = table2cell(T) ;
idx = strfind(T,'A') ;
Read about strfind. If you convert your character array to cell, you can use certain functions and make the code run faster.
  1 件のコメント
Russell Marki
Russell Marki 2018 年 3 月 21 日
If I want all the words that begin with 'A' or 'B', have a second letter of 'D' or 'B', have a third ... . Right now I have a fairly quick way to do this, but I have a need for speed.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeData Type Conversion についてさらに検索

タグ

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by