Thread Subject: Convert number to array

Subject: Convert number to array

From: Brandon

Date: 8 Mar, 2009 22:29:01

Message: 1 of 13

Hello,

I've been doing project euler exercises as a way of revising matlab.
For a number of the problems I have come up with solutions requiring a number be converted into a vector of its parts

for example: 5243 becomes [5, 2, 4, 3]

I am wanting to know if matlab has a builtin function to perform this task (and the reverse).

My current approach is:
num2vec = @(x) str2num(regexprep(num2str(fix(x)),'\d','$0,'));

which is then used as follows:
b = arrayfun(num2vec, a, 'UniformOutput', false);

Now I do realise this would be quicker as an mfile with a loop which uses mod and powers of 10. I am more looking for either a more efficient anonymous function or a builtin method.

thank you

Subject: Convert number to array

From: Brandon

Date: 8 Mar, 2009 23:47:01

Message: 2 of 13

While playing with something unrelated I found I could do

num2str(1234)*1+'0' => [1, 2 ,3, 4]

Now to work out if i can avoid converting to a string.
(and to reverse this procedure)

Subject: Convert number to array

From: per isakson

Date: 9 Mar, 2009 01:00:20

Message: 3 of 13

On 9 Mar, 00:47, "Brandon"
<bnavra.remove.t...@student.usyd.edu.au.remove.this> wrote:
> While playing with something unrelated I found I could do
>
> num2str(1234)*1+'0' => [1, 2 ,3, 4]
>
> Now to work out if i can avoid converting to a string.
> (and to reverse this procedure)

See: sprintf and sscanf
/per

Subject: Convert number to array

From: Brandon

Date: 9 Mar, 2009 02:49:01

Message: 4 of 13

Thank you for your reply Per

Unfortunately, it has confused me a little.

I believe sprintf and sscanf take string inputs whilst I am trying to avoid converting the number to a string.

per isakson <poi@bim.kth.se> wrote in message <bceecd19-8be5-4543-99d4-61b10f951198@s28g2000vbp.googlegroups.com>...
> On 9 Mar, 00:47, "Brandon"
> <bnavra.remove.t...@student.usyd.edu.au.remove.this> wrote:
> > While playing with something unrelated I found I could do
> >
> > num2str(1234)*1+'0' => [1, 2 ,3, 4]
> >
> > Now to work out if i can avoid converting to a string.
> > (and to reverse this procedure)
>
> See: sprintf and sscanf
> /per

Subject: Convert number to array

From: per isakson

Date: 9 Mar, 2009 03:28:02

Message: 5 of 13

"Brandon" <bnavra.remove.this@student.usyd.edu.au.remove.this> wrote in message <gp202t$fqt$1@fred.mathworks.com>...
> Thank you for your reply Per
>
> Unfortunately, it has confused me a little.
>
> I believe sprintf and sscanf take string inputs whilst I am trying to avoid converting the number to a string.
>
> per isakson <poi@bim.kth.se> wrote in message <bceecd19-8be5-4543-99d4-61b10f951198@s28g2000vbp.googlegroups.com>...
> > On 9 Mar, 00:47, "Brandon"
> > <bnavra.remove.t...@student.usyd.edu.au.remove.this> wrote:
> > > While playing with something unrelated I found I could do
> > >
> > > num2str(1234)*1+'0' => [1, 2 ,3, 4]
> > >
> > > Now to work out if i can avoid converting to a string.
> > > (and to reverse this procedure)
> >
> > See: sprintf and sscanf
> > /per

sscanf( sprintf( '%u', 12345 ), '%1d' )'
ans =
     1 2 3 4 5
>>

I believe this is the most compact way. An alternative is a loop .... divide by ten ... etc.
/per

Subject: Convert number to array

From: Brandon

Date: 9 Mar, 2009 05:53:01

Message: 6 of 13

Hi per,

Thats a very novel approach you have taken.
It didn't occur to me to use the sscanf format specifier with padding.

However, can it operate on a vector of values. I have had difficulty with it.
a = 1000:9999;
b = sscanf( sprintf( '%u', a ), '%1d' )';

The above gives me an answer which is [36000 x 1]

I get the correct answer [9000 x 4] with my other approach
a = 1000:9999;
b=num2str(a').*1-'0';

I've been thinking that there may be a way to do this by converting the number to a byte array and bit-twiddling...but I need to give that more thought.

Thanks
Brandon

"per isakson" <poi.nospam@bimDOTkthDOT.se> wrote in message <gp22c2$dpn$1@fred.mathworks.com>...
> "Brandon" <bnavra.remove.this@student.usyd.edu.au.remove.this> wrote in message <gp202t$fqt$1@fred.mathworks.com>...
> > Thank you for your reply Per
> >
> > Unfortunately, it has confused me a little.
> >
> > I believe sprintf and sscanf take string inputs whilst I am trying to avoid converting the number to a string.
> >
> > per isakson <poi@bim.kth.se> wrote in message <bceecd19-8be5-4543-99d4-61b10f951198@s28g2000vbp.googlegroups.com>...
> > > On 9 Mar, 00:47, "Brandon"
> > > <bnavra.remove.t...@student.usyd.edu.au.remove.this> wrote:
> > > > While playing with something unrelated I found I could do
> > > >
> > > > num2str(1234)*1+'0' => [1, 2 ,3, 4]
> > > >
> > > > Now to work out if i can avoid converting to a string.
> > > > (and to reverse this procedure)
> > >
> > > See: sprintf and sscanf
> > > /per
>
> sscanf( sprintf( '%u', 12345 ), '%1d' )'
> ans =
> 1 2 3 4 5
> >>
>
> I believe this is the most compact way. An alternative is a loop .... divide by ten ... etc.
> /per

Subject: Convert number to array

From: us

Date: 9 Mar, 2009 06:46:15

Message: 7 of 13

"Brandon"
> I get the correct answer [9000 x 4] with my other approach
> a = 1000:9999;
> b=num2str(a').*1-'0';

yes, but only in certain cases...
moreover
- the .*1 is not necessary...
- use INT2STR, which is called by NUM2STR directly...
- these functions come with considerable overhead re your problem...

     a=98:102;
     b=num2str(a.')-'0'
%{
     -16 9 8
     -16 9 9
       1 0 0
       1 0 1
       1 0 2
%}
% - you then need to do this
     b(b<0)=0;

% anoter solution could be
     nd=ceil(log10(max(a)));
% -or- select ND yourself...
% nd=nd+your_digits;
     fmt=sprintf('%%%d.%dd',nd,nd)
     r=reshape(sprintf(fmt,a)-'0',nd,[]).'
%{
     0 9 8
     0 9 9
     1 0 0
     1 0 1
     1 0 2
%}

us

Subject: Convert number to array

From: Brandon

Date: 9 Mar, 2009 09:36:01

Message: 8 of 13

us,

Thank you for your reply.
I hadn't considered the boundary conditions (arrays with variable length digits) as I was looking for either a builtin function or a one-liner.

However, from what I can see there doesn't appear to be a way to avoid using string functions. I guess I will have to resolve myself to use an m-file.

My initial attempt:
function res = num2array(a)
    numlen = ceil(log10(max(a)));
    res = zeros(size(a,2),numlen);
    
    for i =1:numlen
        res(:,numlen-i+1) = mod(a,10)';
        a = fix(a /10);
    end
end

Can the above be improved?

Subject: Convert number to array

From: us

Date: 9 Mar, 2009 09:54:02

Message: 9 of 13

"Brandon" wrote:
> us,
> My initial attempt:
> function res =3D num2array(a)
> =A0 =A0 numlen =3D ceil(log10(max(a)));
> =A0 =A0 res =3D zeros(size(a,2),numlen);
> =A0 =A0 for i =3D1:numlen
> =A0 =A0 =A0 =A0 res(:,numlen-i+1) =3D mod(a,10)';
> =A0 =A0 =A0 =A0 a =3D fix(a /10);
> =A0 =A0 end
> end
> Can the above be improved...

one of the solutions
- note: your function does NOT allow for numel(a) > 1

function res=3Dfoo(a)
     ten=3D10.^(floor(log10(max(a))):-1:0);
     res=3Dfix(mod(bsxfun(@rdivide,a,ten),10));
end

% example
     d=3Dceil(1000*rand(5,1));
     r=3Dfoo(d);
     disp([d,r]);
%{
%
      31 0 3 1
     417 4 1 7
     934 9 3 4
     225 2 2 5
     175 1 7 5
%}

us

Subject: Convert number to array

From: us

Date: 9 Mar, 2009 10:00:13

Message: 10 of 13


"Brandon" wrote:
> us,
> My initial attempt:
> function res = num2array(a)
> numlen = ceil(log10(max(a)));
> res = zeros(size(a,2),numlen);
> for i =1:numlen
> res(:,numlen-i+1) = mod(a,10)';
> a = fix(a /10);
> end
> end
> Can the above be improved...


one of the solutions
- note: your function does NOT allow for numel(a) > 1
- note: second post via google...

function res=foo(a)
     ten=10.^(floor(log10(max(a))):-1:0);
     res=fix(mod(bsxfun(@rdivide,a,ten),10));
end


% example
     d=ceil(1000*rand(5,1));
     r=foo(d);
     disp([d,r]);
%{
%
      31 0 3 1
     417 4 1 7
     934 9 3 4
     225 2 2 5
     175 1 7 5
%}

us

Subject: Convert number to array

From: brandon.navra@gmail.com

Date: 9 Mar, 2009 10:11:48

Message: 11 of 13

us,

Your solution is very appealling to me, esp the brevity of it.

I looked at mine again. I works only on row vectors

so
d=[ceil(1000*rand(5,1))]' works

d=ceil(1000*rand(5,1)); doesn't

Anyway, I think i'll continue ahead with your solution and put his
query to bed

Thank you
Brandon

Subject: Convert number to array

From: brandon.navra@gmail.com

Date: 9 Mar, 2009 10:23:56

Message: 12 of 13

us,

Your solution is very appealling to me, esp the brevity of it.

I looked at mine again. I works only on row vectors

so
d=[ceil(1000*rand(5,1))]' works

d=ceil(1000*rand(5,1)); doesn't

Anyway, I think i'll continue ahead with your solution and put his
query to bed

Thank you
Brandon

Subject: Convert number to array

From: Brandon

Date: 9 Mar, 2009 10:32:01

Message: 13 of 13

us,

Your solution is very appealling to me, esp the brevity of it.

I looked at mine again. I works only on row vectors

so
d=[ceil(1000*rand(5,1))]' works

d=ceil(1000*rand(5,1)); doesn't

Anyway, I think i'll continue ahead with your solution and put his
query to bed

Thank you
Brandon

ps. I tried posting with google, but it kept showing my email address, which is not preferable

Tags for this Thread

Add a New Tag:

Separated by commas
Ex.: root locus, bode

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

rssFeed for this Thread

Contact us at files@mathworks.com