Objectmix
Tags Register Mark Forums Read

circular shift array : C

This is a discussion on circular shift array within the C forums in Programming Languages category; Hi, What is a simple way to shift the elements in an array, circularly? Is there a way to do it so that you don't need a separate storage array? IE I want to shift array A{1,2,3,4,5,6,7,8} by 3 to the right. The result would be B{6,7,8,1,2,3,4,5) Thanks! B...


Object Mix > Programming Languages > C > circular shift array

C comp.lang.c usenet archive

Reply

 

LinkBack Thread Tools
  #1  
Old 07-30-2007, 10:05 PM
Junior Member
 
Join Date: Nov 2009
Posts: 0
Application Development is on a distinguished road
Default circular shift array

Hi,

What is a simple way to shift the elements in an array, circularly? Is
there a way to do it so that you don't need a separate storage array?

IE I want to shift array A{1,2,3,4,5,6,7,8} by 3 to the right. The result
would be B{6,7,8,1,2,3,4,5)

Thanks!
B



  #2  
Old 07-30-2007, 10:36 PM
Junior Member
 
Join Date: Nov 2009
Posts: 0
Application Development is on a distinguished road
Default Re: circular shift array

On Mon, 30 Jul 2007 22:04:42 -0500, "Bint" <bint@csgs.com> wrote:

>Hi,
>
> What is a simple way to shift the elements in an array, circularly? Is
>there a way to do it so that you don't need a separate storage array?
>
>IE I want to shift array A{1,2,3,4,5,6,7,8} by 3 to the right. The result
>would be B{6,7,8,1,2,3,4,5)
>


You don't need a separate array; one temporary object to hold the
rightmost value is sufficient.

Save rightmost value
Loop through array from right to left starting at next to
rightmost value
Save value in next element to the right
Store saved value in first element
Repeat as often as necessary.

You could make a function out of it (or even a macro)

void rshift_int(int array[], size_t num_elements, int
iterations){...}


Remove del for email
  #3  
Old 07-31-2007, 12:43 AM
Junior Member
 
Join Date: Nov 2009
Posts: 0
Application Development is on a distinguished road
Default Re: circular shift array

On Jul 30, 7:36 pm, Barry Schwarz <schwa...@doezl.net> wrote:
> On Mon, 30 Jul 2007 22:04:42 -0500, "Bint" <b...@csgs.com> wrote:
> >Hi,

>
> > What is a simple way to shift the elements in an array, circularly? Is
> >there a way to do it so that you don't need a separate storage array?

>
> >IE I want to shift array A{1,2,3,4,5,6,7,8} by 3 to the right. The result
> >would be B{6,7,8,1,2,3,4,5)

>
> You don't need a separate array; one temporary object to hold the
> rightmost value is sufficient.
>
> Save rightmost value
> Loop through array from right to left starting at next to
> rightmost value
> Save value in next element to the right
> Store saved value in first element
> Repeat as often as necessary.
>
> You could make a function out of it (or even a macro)
>
> void rshift_int(int array[], size_t num_elements, int
> iterations){...}
>
> Remove del for email


Barry is correct. I did this kind of thing.

One suggestion. If you have a bunch of arrays, instead of a temporary
object, you may want to make each array one longer than needed, and
use the extra element as the temporary object. It may make your code
easier to read and maintain.

Daniel Goldman

  #4  
Old 07-31-2007, 03:15 AM
Junior Member
 
Join Date: Nov 2009
Posts: 0
Application Development is on a distinguished road
Default Re: circular shift array

Bint said:

> Hi,
>
> What is a simple way to shift the elements in an array, circularly?
> Is
> there a way to do it so that you don't need a separate storage array?
>
> IE I want to shift array A{1,2,3,4,5,6,7,8} by 3 to the right. The
> result would be B{6,7,8,1,2,3,4,5)


If you must shift them at all (see below):

(a) you /can/ get away with temporary storage for a single value, but
this means you have to move every item individually, instead of taking
advantage of memcpy - so get some temporary storage if you can;
(b) minimise the shift. If the array has 8 members and you want to shift
5 to the left, you can reduce this to 8 - 5 = 3 by shifting in the
opposite direction, so you never need temporary storage for more than
half the items in the array;
(c) if you have temporary storage capable of storing a number of
elements at least equal to the amount W of your shift, use it to store
*all* of the W leftmost items (if you're shifting left) or the W
rightmost items (if you're shifting right). That way, you can do the
whole thing in two memcpy's and a memmove.

An easier way, which doesn't involve any shifting at all, is to maintain
an object whose purpose is to store the index of the first item. Then
you just process the array as follows:

idx = head;
for(i = 0; i < n; i++)
{
if(idx++ == n) /* idx = (head + i) % n is shorter, but costlier */
{
idx = 0;
}
proc(arr[idx]);
}

and there is no need to shift anything at all!

Also investigate circular linked lists.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
  #5  
Old 07-31-2007, 03:30 AM
Junior Member
 
Join Date: Nov 2009
Posts: 0
Application Development is on a distinguished road
Default Re: circular shift array

Richard Heathfield said:

<snip>

> (a) you /can/ get away with temporary storage for a single value, but
> this means you have to move every item individually, instead of taking
> advantage of memcpy


Er, I meant memmove

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
  #6  
Old 07-31-2007, 03:58 AM
Junior Member
 
Join Date: Nov 2009
Posts: 0
Application Development is on a distinguished road
Default Re: circular shift array

In article <N_adnSlUjZ1NczPb4p2dnAA@bt.com>,
Richard Heathfield <rjh@see.sig.invalid> wrote:
>An easier way [to deal with circular queues], which doesn't involve
>any shifting at all, is to maintain an object whose purpose is to
>store the index of the first item. Then you just process the array
>as follows:
>
>idx = head;
>for(i = 0; i < n; i++)
>{
> if(idx++ == n) /* idx = (head + i) % n is shorter, but costlier */


I believe you mean "if (++idx == n)" here. (The post-increment
version can be made to work by changing other values, but it is
then not equivalent to the "idx = (head + i) % n" method.)

Or, one could say:

idx = (head + i) % n; /* if (idx++ == n) is faster, but less correct */

which suggests perhaps you are doing premature optimization. :-)

> {
> idx = 0;
> }
> proc(arr[idx]);
>}


Also, usually one wants to process first, then test ++idx against n.
(Again, "increment before processing" can be made to work, but is
more complicated.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
  #7  
Old 07-31-2007, 04:08 AM
Junior Member
 
Join Date: Nov 2009
Posts: 0
Application Development is on a distinguished road
Default Re: circular shift array

dan <dagoldman@yahoo.com> writes:

> On Jul 30, 7:36 pm, Barry Schwarz <schwa...@doezl.net> wrote:
>> On Mon, 30 Jul 2007 22:04:42 -0500, "Bint" <b...@csgs.com> wrote:
>> >Hi,

>>
>> > What is a simple way to shift the elements in an array, circularly? Is
>> >there a way to do it so that you don't need a separate storage array?

>>
>> >IE I want to shift array A{1,2,3,4,5,6,7,8} by 3 to the right. The result
>> >would be B{6,7,8,1,2,3,4,5)

>>
>> You don't need a separate array; one temporary object to hold the
>> rightmost value is sufficient.
>>
>> Save rightmost value
>> Loop through array from right to left starting at next to
>> rightmost value
>> Save value in next element to the right
>> Store saved value in first element
>> Repeat as often as necessary.
>>
>> You could make a function out of it (or even a macro)
>>
>> void rshift_int(int array[], size_t num_elements, int
>> iterations){...}
>>
>> Remove del for email

>
> Barry is correct. I did this kind of thing.
>
> One suggestion. If you have a bunch of arrays, instead of a temporary
> object, you may want to make each array one longer than needed, and
> use the extra element as the temporary object. It may make your code
> easier to read and maintain.
>
> Daniel Goldman
>


or just have the array double its normal size with duplicate copies and
merely shuffle a pointer to the first element .... no Memory move at all
then.
  #8  
Old 07-31-2007, 04:33 AM
Junior Member
 
Join Date: Nov 2009
Posts: 0
Application Development is on a distinguished road
Default Re: circular shift array

Chris Torek said:

> In article <N_adnSlUjZ1NczPb4p2dnAA@bt.com>,
> Richard Heathfield <rjh@see.sig.invalid> wrote:
>>An easier way [to deal with circular queues], which doesn't involve
>>any shifting at all, is to maintain an object whose purpose is to
>>store the index of the first item. Then you just process the array
>>as follows:
>>
>>idx = head;
>>for(i = 0; i < n; i++)
>>{
>> if(idx++ == n) /* idx = (head + i) % n is shorter, but costlier */

>
> I believe you mean "if (++idx == n)" here.


Er, kind of. What I really meant was:

proc(arr[idx]);
if(++idx == n)
{
idx = 0;
}

> (The post-increment
> version can be made to work by changing other values, but it is
> then not equivalent to the "idx = (head + i) % n" method.)
>
> Or, one could say:
>
> idx = (head + i) % n; /* if (idx++ == n) is faster, but less
> correct */
>
> which suggests perhaps you are doing premature optimization. :-)


Well, it does avoid a division. Had I got it right, I think it would
have been a reasonable thing to do. :-)

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Reply

Thread Tools


Similar Threads

Thread Thread Starter Forum Replies Last Post
Re: How to make a global array by shift register usenet labview 6 12-11-2007 09:40 PM
why does shift stop my loop over this array usenet Javascript 1 09-10-2007 11:18 AM
circular shift array usenet C 2 07-31-2007 07:10 AM
Array an object in a circular pattern... usenet Adobe illustrator 9 06-02-2007 01:33 AM
How to do the shift bit operation in Array usenet vhdl 12 01-26-2007 08:40 PM


All times are GMT -5. The time now is 08:28 AM.

Managed by Infnx Pvt Ltd.