필터 지우기
필터 지우기

Structure Indexing to Find Words

조회 수: 3 (최근 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 CenterFile Exchange에서 Structures에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by