4

I have the following string in matlab

V= 'abcdefghijklmnñopqrstuvwxyz';

Then I have a word of 9 characters consisting of chars from my 'V' alphabet.

k = 'peligroso';

I want to create a square matrix (3x3) with the indices of my word 'k' according to my alphabet, this would be the output. (Note that the range I'm considering is 0 to 26, so 'a' char does have index 0)

   16    4     11
   8     6     18
   15    19    15

My code for doing this is:

K = [findstr(V, k(1))-1 findstr(V, k(2))-1 findstr(V, k(3))-1;findstr(V, k(4))-1 findstr(V, k(5))-1 findstr(V, k(6))-1; findstr(V, k(7))-1 findstr(V, k(8))-1 findstr(V, k(9))-1];

But I think there must be a more elegant solution to achieve the same, any ideas?

PS: I'm not using ASCII values since char 'ñ' must be inside my alphabet

3 Answers 3

7

For a loop-free solution, you can use ISMEMBER, which works on strings as well as on numbers:

K = zeros(3); %# create 3x3 array of zeros

[~,K(:)] = ismember(k,V); %# fill in indices

K = K'-1; %# make K conform to expected output
Sign up to request clarification or add additional context in comments.

3 Comments

I'm getting the following error with your code "??? [~,K(:)] = ismember(k,V); | Error: Expression or statement is incorrect--possibly unbalanced (, {, or [." The comma is causing the error
@JorgeZapata: The tilde only became legal in newer versions of Matlab. Please replace it with e.g. dummy, i.e. [dummy,K(:)] = ismember(k,V); %# fill in indices
That was the thing, thanks I find your code more elegant than the others.
2

Since strings are just arrays of characters, it is easy to manipulate them using the usual array-processing functions.

For example, we can use arrayfun to create a new array by applying the specified function, which produces an output array of the same size. Using reshape we can form the desired 3x3 shape. Note that we transpose at the end since MATLAB's reshape handles arrays in column-major order.

K = reshape(arrayfun(@(x) findstr(V, x)-1, k), 3,3)'

Alternatively, since MATLAB lets you index matrices using a single index, which reads the entries of the matrix in column major order, we can construct an empty matrix and build its entries up one-by-one.

K = zeros(3,3)
for i=1:9
    K(i) = findstr(V, k(i))-1;
end
K = K'

1 Comment

From findstr: > Note: findstr will be removed in a future release. Use strfind instead. But besides that: perfect +1
2

I am fond of @Jonas' solution (ismember), I think it's the most elegant way to go here. But, just to provide another solution:

V = 'abcdefghijklmnñopqrstuvwxyz';
k = 'peligroso';

K = reshape( bsxfun(@eq, (k-0).', V-0) * (1:numel(V)).', 3,3).'

(forgive the SO highlighting)

The advantage of this would be that this uses built-in functions exclusively (ismember is not built-in, at least, not on my Matlab R2010b). This means that this solution might be faster than ismember, but

  1. You'll have to test whther that is actually true, and if true,

  2. you should have cases complex and large enough to justify losing the readability of ismember

Note that indices in Matlab are 1-based, meaning that V(1) = a. The solution above produces a 1-based answer, while you provide a 0-based example. Just subtract 1 from the line above if you really need 0-based indices.

1 Comment

Have a look at the syntax highlighting plugin in the Matlab tag wiki - it will make Matlab code look all pretty!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.