Compare two numeric cell arrays
    4 visualizaciones (últimos 30 días)
  
       Mostrar comentarios más antiguos
    
    Russell Marki
 el 17 de En. de 2017
  
    
    
    
    
    Comentada: Russell Marki
 el 17 de En. de 2017
            I have two huge cells, a dictionary and a set of possible hands in scrabble. I want to compare the two and find what arrays match
myAletters = ['D','I','R','N','E','E','P'];
myAletters = upper(myAletters);
myAletters = int8(myAletters);
myAletters = myAletters-64;
hand_count=0;
for i=1:length(myAletters)
      hand_interim_combination=nchoosek(myAletters,i);
      for j=1:length(hand_interim_combination(:,1))
          hand_interim_permutation=perms(hand_interim_combination(j,:));
           for k=1:length(hand_interim_permutation(:,1))
               hand_count=hand_count+1;
               hand{hand_count}=hand_interim_permutation(k,:);
           end
      end
end
end
load('myDict.mat');
word_plays=ismember(hand,myDict);
Ismember won't work because it has to be strings, going one by one won't work because it takes too long. Wat do?
2 comentarios
  Stephen23
      
      
 el 17 de En. de 2017
				
      Editada: Stephen23
      
      
 el 17 de En. de 2017
  
			"going one by one won't work because it takes too long. Wat do?"
Stop ignoring mlint messages in the Editor. There is already one message in your code telling you that the way you have written it is going to be slow. The message even tells you how to solve this issue:

Also note that the following code does not create an array of separate characters, because [] is a concatenation operator, not a list operators as many beginners think:
 >> myAletters = ['D','I','R','N','E','E','P']
 myAletters =
 DIRNEEP
That code is therefore equivalent to simply writing this:
 >> myAletters = 'DIRNEEP'
 myAletters =
 DIRNEEP
Respuesta aceptada
  Stephen23
      
      
 el 17 de En. de 2017
        
      Editada: Stephen23
      
      
 el 17 de En. de 2017
  
      Once I got rid of that unnecessary conversion to numeric value then this task becomes a lot easier. I also preallocated the cell array hand to significantly speed the code up.
myAletters = 'DIRNEEP';
hand = cell(1,floor(exp(1)*factorial(numel(myAletters)))-1);
hand_count=0;
for i=1:length(myAletters)
      hand_interim_combination=nchoosek(myAletters,i);
      for j=1:length(hand_interim_combination(:,1))
          hand_interim_permutation=perms(hand_interim_combination(j,:));
           for k=1:length(hand_interim_permutation(:,1))
               hand_count=hand_count+1;
               hand{hand_count}=hand_interim_permutation(k,:);
           end
      end
end
%load('myDict.mat');
myDict = {'IRE','PEER','XYZ'};
word_plays = ismember(hand,myDict);
and checking the output:
>> hand(word_plays) 
ans = 
  'IRE'    'IRE'    'PEER'    'PEER'
I also tidied up the formatting (crtl+I), replaced unpredictable length with reliable size, and renamed variables to make it more readable (for me):
vec = 'DIRNEEP';
hand = cell(1,floor(exp(1)*factorial(numel(vec)))-1);
itr = 0;
for m = 1:numel(vec)
    cmb = nchoosek(vec,m);
    for n = 1:size(cmb,1)
        prm = perms(cmb(n,:));
        for k = 1:size(prm,1)
            itr = itr+1;
            hand{itr} = prm(k,:);
        end
    end
end
Perhaps the simplest solution would be to use cellstr instead of the innermost loop:
vec = 'DIRNEEP';
hand = cell(1,2^numel(vec)-1);
k = 0;
for m = 1:numel(vec)
    cmb = nchoosek(vec,m);
    for n = 1:size(cmb,1)
        k = k+1;
        hand{k} = cellstr(perms(cmb(n,:)));
    end
end
hand = vertcat(hand{:});
Note that these are all just improvements on your algorithm. With a large dictionary a more efficient algorithm might use the small number of available letters to iteratively select smaller sets of the dictionary, until matches are achieved.
Más respuestas (0)
Ver también
Categorías
				Más información sobre Structures en Help Center y File Exchange.
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


