How to combine numerical values into one?

12 次查看(过去 30 天)
Hi all
I've got a question for you. Lets say I have two vectors a and b, respectively, with the following content:
a = [0 1 1]
b = [1 0 1]
I wish to combine these with a one-liner (preferably a built-in function) so that I get
c = [01 10 11]
How to go about this? I don't mind if the elements in c are strings.
Your help is much appreciated. Cheers!
  1 个评论
the cyclist
the cyclist 2015-3-17
Is it OK if c is one string? Or do you need three distinct strings, stored in a cell array?

请先登录,再进行评论。

回答(4 个)

per isakson
per isakson 2015-3-17
编辑:per isakson 2015-3-17
"I don't mind if the elements in c are strings." &nbsp The leading zero in 01 requires a string. Try
>> sprintf( '%1d%1d ', [a;b] )
ans =
01 10 11
or better
>> str = strtrim( sprintf( '%1d%1d ', [a;b] ) )
str =
01 10 11
&nbsp
Addendum triggered by comment
>> cac = strsplit( strtrim( sprintf( '%1d%1d ', [a;b] ) ) )
cac =
'01' '10' '11'
>> cac{2}
ans =
10
>>
>> C = textscan( cac{2}, '%1d%1d' );
>> C{:}
ans =
1
ans =
0
or to output strings
>> C = textscan( cac{2}, '%1c%1c' );
>> C{:}
ans =
1
ans =
0
or just
>> cac{2}(1)
ans =
1
>> cac{2}(2)
ans =
0
  1 个评论
Gunnar
Gunnar 2015-3-17
I think we are getting somewhere.
Is there a way to make generalize this? Also, the length of the answer in this case is 9 (it counts the spaces I guess), but can we make the length equal to 3? That way one can easily access 01, 10 and 11 and convert it back to 0 and 1, 1 and 0, and 1 and 1, respectively.

请先登录,再进行评论。


Guillaume
Guillaume 2015-3-17
As others have said, the only way you can keep that leading zero is by using strings since leading zero have no meaning with numbers. Using strings is expensive though in term of processing time.
I'm not sure why you can't keep your states as a 2D matrix, in my opinion it's the easiest to manipulate and visualise. If you don't want to keep your states as a matrix, then the next best option would be to keep them as a decimal numbers, since after all your combination of states are just binary representation of numbers. A generic way to convert from your states to a vector of number would be:
fromstates = @(varargin) arrayfun(@(varargin) polyval(cell2mat(varargin), 2), varargin{:});
e.g:
>>fromstates([0 1 1], [1 0 1])
ans =
1 2 3
>>fromstates([0 1 0 1], [1 0 0 1], [1 1 0 0])
ans =
3 5 0 6
You can easily test each bit of the states with bitget:
>>bitget([3 5 0 6], 2)
ans =
1 0 0 1
Or to get all the states back all at once:
deal2 = @(c) c{:}; %helper function
tostates = @(decvalues) deal2(arrayfun(@(bit) bitget(decvalues, bit), nargout:-1:1, 'UniformOutput', false);
>>[a, b, c] = tostates([3 5 0 6])
a =
0 1 0 1
b =
1 0 0 1
c =
1 1 0 0
If you really want strings, then a generic way to convert to string is:
fromstate = @(varargin) num2cell(char(vertcat(varargin{:}) + '0')', 2)';
>>fromstate([0 1 0 1], [1 0 0 1], [1 1 0 0])
ans =
'011' '101' '000' '110'
And back
deal2 = @(c) c{:};
tostates = @(strings) deal2(num2cell(vertcat(strings{:})' - '0', 2);
>>[a, b, c] = tostates({'011' '101' '000' '110'})
a =
0 1 0 1
b =
1 0 0 1
c =
1 1 0 0

Jos (10584)
Jos (10584) 2015-3-17
Use the power of ARRAYFUN:
a = [0 1 1]
b = [1 0 1]
c = arrayfun(@(k) sprintf('%d%d',a(k),b(k)),1:numel(a),'un',0)
a2 = arrayfun(@(k) c{k}(1)-'0',1:numel(c))
b2 = arrayfun(@(k) c{k}(2)-'0',1:numel(c))

Gunnar
Gunnar 2015-3-17
Many of the answers look rather "complicated". Isn't there anything more "straightforward"?
Thanks for posting, everyone.
  3 个评论
John D'Errico
John D'Errico 2015-3-17
The problem is, you want to keep the pair [0 1] as a pair. If you convert it to a number, then clearly 01 is just 1. MATLAB does not recognize high order zero bits as adding useful information. This is a property of floating point numbers.
SOOOOO, if you insist on keeping those values together, they cannot be numeric. So you must be willing to either keep them as essentially a 1x2 element array of numbers, or as a string. Those are your choices. And operations on strings are never quite as trivial as they are on numbers.
Gunnar
Gunnar 2015-3-17
@per isakson: The reason is that I would like to use 0 and 1 to generate different states for different depth using the combvec function. For example:
depth 1: 0 or 1
depth 2: 00 01 10 11
depth 3: 001 010 001 100 101 110 111
...and so on...
Since 0 and 1 in each state corresponds to some data stored elsewhere in my code, I would like to convert it back to numerical values, multiply it with my data, and sum it all together.
Of course there are other ways to go about this that I am working on, but if there was a simple solution to this proposed here then I would try and go for that.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Characters and Strings 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by