Question

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?

Was it helpful?

Solution 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

OTHER TIPS

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'
    ...

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top