1

UPD: I wish to say sorry to the StackOverflow community for asking a question without making effort to solve the problem by myself. From now on, I'll ask questions only if I really have serious problem

I am now developing the program that generates all the possible permutations of string elements:

I started with:

A = ['Bridge','No Bridge'];
B = ['Asphalt','Concrete','Combined'];
C = ['Fly Ash',' Sulphur','Nothing'];
D = ['Two lanes','Four lanes with barriers'];
E = ['Paid','Non-paid'];
F = ['Mobile','Non-mobile'];
N = length(A)*length(B)*length(C)*length(D)*length(E)*length(F);
out = zeros(N,6);

But now I'm stuck with what to do next. The output needed is something like:

out = 

    'Bridge' 'Asphalt' 'Fly Ash' 'Two lanes' 'Paid' 'Mobile'
    'Bridge' 'Asphalt' 'Fly Ash' 'Two lanes' 'Paid' 'Non-mobile'
    'Bridge' 'Asphalt' 'Fly Ash' 'Two lanes' 'Non-paid' 'Mobile'
    'Bridge' 'Asphalt' 'Fly Ash' 'Two lanes' 'Non-paid' 'Non-mobile' etc

Please, could you suggest the most efficient way to do this?

brainkz
  • 1,335
  • 10
  • 16
  • Welcome to Stackoverflow, it is not a code writing service but aims to help you get your programs working. Please show what code you have written to try and solve the problem and explain what parts are not working. Please also look at the **Help** link at the top of the page and the sections on how to write good questions. – AdrianHHH Mar 11 '14 at 15:44
  • You can get some ideas [here](http://stackoverflow.com/q/19875203) and [here](http://stackoverflow.com/questions/21895335/generate-a-matrix-containing-all-combinations-of-elements-taken-from-n-vectors) (work with the indices, and then use them to index the strings) – Luis Mendo Mar 11 '14 at 15:48
  • For a Python implementation, see the itertools product recipe http://docs.python.org/2/library/itertools.html#itertools.product – IceArdor Mar 11 '14 at 16:49

3 Answers3

5

Use ndgrid to generate all combinations of the indices, and then use those indices to build the result from the strings:

A = {'Bridge','No Bridge'};
B = {'Asphalt','Concrete','Combined'};
C = {'Fly Ash',' Sulphur','Nothing'};
D = {'Two lanes','Four lanes with barriers'};
E = {'Paid','Non-paid'};
F = {'Mobile','Non-mobile'}; %// data. Cell arrays of strings

[a b c d e f] = ndgrid(1:numel(A),1:numel(B),1:numel(C),1:numel(D),1:numel(E),1:numel(F));
out = [A(a(:)).' B(b(:)).' C(c(:)).' D(d(:)).' E(e(:)).' F(f(:)).'];

Or, if you need the results in the order of your example:

[f e d c b a] = ndgrid(1:numel(F),1:numel(E),1:numel(D),1:numel(C),1:numel(B),1:numel(A));
out = [A(a(:)).' B(b(:)).' C(c(:)).' D(d(:)).' E(e(:)).' F(f(:)).'];

This gives

out = 

    'Bridge'       'Asphalt'     'Fly Ash'     'Two lanes'    'Paid'        'Mobile'    
    'Bridge'       'Asphalt'     'Fly Ash'     'Two lanes'    'Paid'        'Non-mobile'
    'Bridge'       'Asphalt'     'Fly Ash'     'Two lanes'    'Non-paid'    'Mobile'    
    'Bridge'       'Asphalt'     'Fly Ash'     'Two lanes'    'Non-paid'    'Non-mobile'
    ...
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
2

First, note that in Matlab, the following square bracket notation: ['Hello', 'World'], does not in fact create an array of string, but concatenates the strings "Hello" and "World" to yield 'HelloWorld'. So, in this case, you should use Cell Arrays instead: A = {'Hello', 'World'} (note the curly brackets).

To answer your question:
Although you could go for something more generic (which you should in real-life code), for now, since you know the arrays of hand, you can simply create nested for loops like this:

A = {'Bridge','No Bridge'};
B = {'Asphalt','Concrete','Combined'};
...    
for aIndex = 1:length(A)
    for bIndex = 1:length(B)
        % add more loop levels here
        fprintf([A{aIndex}, ',', B{bIndex}, '\n']);
    end
end

With ouput:

Bridge,Asphalt
Bridge,Concrete
Bridge,Combined
No Bridge,Asphalt
No Bridge,Concrete
No Bridge,Combined

bavaza
  • 10,319
  • 10
  • 64
  • 103
  • 1
    For *n* input cell arrays, *n* nested for loops are required. This solution isn't generalizable. – IceArdor Mar 11 '14 at 16:47
  • @IceArdor - I'm aware of that. That is why I wrote: "Although you could go for something more generic (which you should in real-life code)". I still think, however, that this straight-forward approach is better for beginners. Usually, one should write some annoying loops in order to realize why a generic solution is superior :). – bavaza Mar 12 '14 at 07:52
0

Though it's not the case in the question asked, but if A, B, C, D, E and F were two element cell arrays, then we could use few dirty tricks -

num1 = (num2str(111111+str2num(dec2bin(0:63))) - '0')';
comp1 = cell(size(num1,2),6);
for k = 1:size(num1,2)
    comp1(k,:) = [A(num1(1,k)) B(num1(2,k)) C(num1(3,k)) D(num1(4,k)) E(num1(5,k)) F(num1(6,k))];
end
Divakar
  • 218,885
  • 19
  • 262
  • 358