How to create a circular array? - c++

I am trying to create a circular reference to array. For example,
float arr1[10] = {0,1,2,3,4,5,6,7,8,9};
Then I use a variable in loop to access elements of array.
for (int i=0;i<10;i++){
std::cout<<arr1[i]<<std::endl;
//other processing using arr1[i] indexing
}
Here, I can only use i<=10. If I want to make i<=16 and if i>10 then index should go to arr1[0] and proceed from there. What are preferable or recommended ways to do this?

You need to use the modulo operator %.
14 % 10 = 4 So just do this with the index you use to access it.

You should use like #Jdman1699 said the modulo operator. Here you find an example:
int position; //the position you want to get
float out = arr1[position%10];

For your specific program, I would simply suggest putting your base for loop inside of another for loop (as it seems that you want to print out all elements of the array many times over, considering your source code). This is because accessing element n is no different than accessing element n + 10. However, if you are planning to create some sort of function to access any element of the array, I would use the modulo operator-base 10. Maybe,
unsigned long int newidx = iptidx%10;
and then work with newidx.

May be u r looking for...
for (int i=0;i<10;i++){
std::cout<<arr1[i%10]<<std::endl;
//other processing using arr1[i] indexing
}

Related

Using nested [ ] operations for std::vector

I am quite new to C++, and i have tried searching for an answer to this and running tests, but many times I'm having trouble figuring out what causes specific behaviors.
My question relates to using nested [ ] operators to access or modify elements in a loop - example:
//Declare
std::vector<int> a1 {10,20,30,40} ;
std::vector<int> a2 {2,3} ;
int S2 = a2.size() ;
//Loop
for(int i = 0 ; i < S2 ; i++){
a1[a2[i]] = a1[a2[i]] + 5000 ;
}
Is this considered ok? I'm asking not only in terms of common practice, but also in terms of efficiency and any other potential factor I need to consider.
Am I supposed to first store a[i] inside a temporary variable inside the loop and then use it to modify my element in vector a2?
I do know that its probably not the best structure and I should be using some other data structure to do this kind of thing, but I just want to understand if this is ok or if it might cause some undefined behavior.
I am developer for a finite element calculation software.
We use this technique in order to access the values inside an element. It helps us to save a lot of memory
BUT: Be aware that it spoils your cache locality. Don't use it in heavy loops, if you can avoid it.
If you need a range checks and performance is not important, you can consider using the at operator of the std::vector
for(const auto & index :a2) {
a1.at(index) += 5000;
}
The at function automatically checks whether n is within the bounds of valid elements in the vector, throwing an out_of_range exception if it is not (i.e., if n is greater than, or equal to, its size). This is in contrast with member operator[], that does not check against bounds.
Moreover, consider using a range based loop
//Loop
for(const auto & index :a2) {
a1[index] += 5000;
}
This is perfectly correct.
But in fact, you just want to iterate the elements of a standard container. C++ allows the range based for statement for that use case:
for (index: a2) {
a1[index] += 5000;
}
I find it more readable even if it is mainly a matter of taste...
Disclaimer: this code makes no control of the validity of the elements of a2 as index of a1.
Looks okay to me. There is no need to create an explicit copy of a2[i].
The only issue I see with something like this is that the argument inside [] should be of type std::size_t instead of int. These integer types encompass different ranges of values, and while std::size_t is an unsigned integer type, int is a signed integer. Beware of using negative indexes or indexes past the last element will likely result in undefined behavior due to out-of-bounds access. But if you can guarantee that the values in a2 are always valid indexes for a1, then these int values will implicitly be converted to std::size_t and things works properly (which seems to be the case in the code example in your question).
I also suggest to convert the loop variable i to std::size_t (and use ++i instead of i++ if you want to be perfect:).
In modern C++, you can also use a range-based for so you don't have use an explicit index variable for accessing a2 values at all:
for (auto indexFromA2 : a2)
a1[indexFromA2] += 5000;
This is less error-prone, because you have to write less logic for managing the element access (and don't have to spell out the types).
I would somehow ensure that the elements in a1 defined in a2 do really exist before trying to access them, otherwise you run out of bounds.
But in regards of nested [] this is fine and there's no need to create another copy of a2 to access a1. The compiler is just unwrapping your expression from inside out.
You can still simplify your code a bit
//Declare
std::vector<int> a1 {10,20,30,40} ;
std::vector<int> a2 {2,3} ;
//Loop
for(int i = 0 ; i < a2.size() ; i++){
if(a1.size()-1 < a2[i]){break;}
a1[a2[i]] += 5000 ;
}

How can I test whether an array element is defined or not (where element can be defined as 0)?

DISCLAIMER: I'm very new to C++ so I'm sorry if this is a stupid question!
I'm trying to read in data to an 1000 element array (double) and then if there are less than 1000 data points to read in ignore the excess elements for the rest of my program.
I've defined a 1000 element array and read in the data and now want to carry out a function on each element which has been defined by the read in data point. How do I test if an element is defined yet? I would use a Boolean algebra test i.e. if(array[i]) {\\function} but the data points can be any natural number including zero, so I don't know if this would work. How would I solve this problem?
The most typical approach to the problem of "the number of things in my array is not fixed ahead of time" is to have a variable that keeps track of how many things are actually in the array. Then, you just loop over that many things.
Since you add the C++ tag, you can (and should) use the vector class to manage everything for you — and you even get the added benefit that it can grow beyond 1000 elements should you happen to have more than that.
(aside: if you insist on sticking with a 1000-long array, you really should make sure you do something appropriate should you actually get more than 1000 data points)
You could initialize your array with a sentinel value like NAN (i.e., not a number):
double array[1000];
std::fill(std::begin(array), std::end(array), NAN);
Then fill sequentially your array:
array[0] = 1.2;
array[1] = 2.3;
array[2] = 3.4;
And then break the loop as soon as this value is met:
for(int i(0); i < 1000; ++i) {
if(isnan(array[i])) break;
function(array[i]);
}
LIVE DEMO

Replacing For loop with memcopy, memmove, or std:copy?

I've got shift function where i an continuously sending it new data points and it will shift my points by an offset of 1. This is to achieve a "graphical shifting" where the points represent points on a graph.
The shifting function is the following:
void Chart_Buffer::ShiftData()
{
for(int index = 0; index < (_channel_Samples - 1); ++index)
{
_sample_Points[index].y = _sample_Points[index + 1].y;
}
return;
}
The problem with this is that it is running through a huge array of up to 800 data points and it does this every time for every new data point added, so i wanted to see if i can optimize this process by shifting all values out by an offset of 1 without running through a for loop. I looked at implementations of memcopy, memmove, and std::copy, but i cant figure out how to use them for my purpose.
Basically, if i have elements 0-799 in the array, i want to shift elements 1-799 by 1 so that i have 0-798 and then just add the new element to the array.
Edit: _sample_Points is type tagPOINT with the following structure:
typedef struct tagPOINT
{
LONG x;
LONG y;
} POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;
It's hard to give a firm answer to this without knowing what you are doing with _sample_Points. But I believe that I can firmly say that copying every element in the array down one is an expensive approach.
In the best case: You just need to access the front of the array and add to the back of the array. If that's the case you're describing a queue.
To add a new element to the back of a queue use: push
To inspect the front element use: front
To "copy everything down one" (just delete the front element) use: pop.
Otherwise you'd be in the case where: You need random access to the array. If that's the case you can still get potentially better performance from a deqeu.
To add a new element to the back of a deque use: push_back
To inspect the front element use: front
To "copy everything down one" (just delete the front element) use: pop_front
So if you use a queue for your _sample_Points Chart_Buffer::ShiftData could be replaced by _sample_Points.pop().
If you use a deque for your _sample_Points Chart_Buffer::ShiftData could be replaced by _sample_Points.pop_front().
It looks like that you are looking for a std::deque. It is a double ended queue, which means you can pop an element from the back and push on the front.
If what you are looking for is to keep the elements of your array in a certain order, this will help you do just that.
Now if you also want to have them contiguously on memory, then you could do it like this:
memmove(array+1, array, sizeof(element)*(array_size-1));
array[0] = new_element;
You cannot do this without less operations than you are already doing, whether you spell all of them or you call an algorithm. The problem is that the operation is not what you described initially, it is not shifting the data, but shifting part of the data (only the y coordinate) but leaving the other half as it is.
If you don't want to spell out the operation, you can play with the transform algorithm in a way similar to the answer by id256, but I am not sure whether that is an improvement really, the loop in the question is easier and cleaner than the transform...
If it is an acceptable amount of refactoring of your code, you could also let go of tagPOINT and instead of having one _sample_Points, have two arrays, one for the x and one for the y. Then you can memmove() the array of ys. Like:
LONG _sample_Points_x[DIMENSION];
LONG _sample_Points_y[DIMENSION];
void Chart_Buffer::ShiftData() {
memmove(_sample_Points_y, _sample_Points_y + 1, (DIMENSION-1) * sizeof _sample_Points_y[0]);
}

push_back/append or appending a vector with a loop in C++ Armadillo

I would like to create a vector (arma::uvec) of integers - I do not ex ante know the size of the vector. I could not find approptiate function in Armadillo documentation, but moreover I was not successfull with creating the vector by a loop. I think the issue is initializing the vector or in keeping track of its length.
arma::uvec foo(arma::vec x){
arma::uvec vect;
int nn=x.size();
vect(0)=1;
int ind=0;
for (int i=0; i<nn; i++){
if ((x(i)>0)){
ind=ind+1;
vect(ind)=i;
}
}
return vect;
}
The error message is: Error: Mat::operator(): index out of bounds.
I would not want to assign 1 to the first element of the vector, but could live with that if necessary.
PS: I would really like to know how to obtain the vector of unknown length by appending, so that I could use it even in more general cases.
Repeatedly appending elements to a vector is a really bad idea from a performance point of view, as it can cause repeated memory reallocations and copies.
There are two main solutions to that.
Set the size of the vector to the theoretical maximum length of your operation (nn in this case), and then use a loop to set some of the values in the vector. You will need to keep a separate counter for the number of set elements in the vector so far. After the loop, take a subvector of the vector, using the .head() function. The advantage here is that there will be only one copy.
An alternative solution is to use two loops, to reduce memory usage. In the first loop work out the final length of the vector. Then set the size of the vector to the final length. In the second loop set the elements in the vector. Obviously using two loops is less efficient than one loop, but it's likely that this is still going to be much faster than appending.
If you still want to be a lazy coder and inefficiently append elements, use the .insert_rows() function.
As a sidenote, your foo(arma::vec x) is already making an unnecessary copy the input vector. Arguments in C++ are by default passed by value, which basically means C++ will make a copy of x before running your function. To avoid this unnecessary copy, change your function to foo(const arma::vec& x), which means take a constant reference to x. The & is critical here.
In addition to mtall's answer, which i agree with,
for a case in which performance wasn't needed i used this:
void uvec_push(arma::uvec & v, unsigned int value) {
arma::uvec av(1);
av.at(0) = value;
v.insert_rows(v.n_rows, av.row(0));
}

Implementing own quicksort on dynamic array

I have to implement my own sort on a dynamic string array, e.g. of such array is:
string * sortArray;
I then read in the size of the array from a text file and make the array as long as needed and fill it. So, I have...
sortArray = new string[_numberOfNames];
for(int i = 0; i < _numberOfNames; ++i){
sin >> _data[i];
}
Now I need to create my own sorting method and I thought I'd go with quicksort. My problem is, I'm not sure how to go about it.
When I choose a pivot, how can I then go about setting up two more dynamic string arrays to put the lower values and highers values in to, then recurse on? There is no way of knowing before hand how big each array needs to be before I start putting values into them.
I thought I could do something like define the size of each array as being the same as the array being sorted, and then some how remove any unwanted empty spaces from the end, but I'm not sure this is possible?
Any help would be much appreciated.
P.S. I know about the std::sort, I already have this in the program, I'm just trying to implement a sort myself.
Two options as from the comments above:
1.) Use std::vector. There you can have variable size arrays.
2.) Use an "in place" version of quicksort that does the sorting in your original array. See http://en.wikipedia.org/wiki/Quicksort#In-place_version
Lets say you have array size N
and you pivot value is x
what you should do is like that, have two pointers one to the beginning(0) and one to the end (N-1). they should both move to the middle. when ever the beginning pointer value is greater than x and the end pointer value is lower than x switch their values. after you finished and placed x in his new location (where the two pointers met) continue recursionally for the part left to x and right to x.