I've developed a method called "rotate" to my stack object class. What I did was that if the stack contains elements: {0,2,3,4,5,6,7} I would needed to rotate the elements forwards and backwards.
Where if i need to rotate forwards by 2 elements, then we would have, {3,4,5,6,7,0,2} in the array. And if I need to rotate backwards, or -3 elements, then, looking at the original array it would be, {5,6,7,0,2,3,4}
So the method that I have developed works fine. Its just terribly ineffecient IMO. I was wondering if I could wrap the array around by using the mod operator? Or if their is useless code hangin' around that I havent realized yet, and so on.
I guess my question is, How can i simplify this method? e.g. using less code. :-)
void stack::rotate(int r)
{
int i = 0;
while ( r > 0 ) // rotate postively.
{
front.n = items[top+1].n;
for ( int j = 0; j < bottom; j++ )
{
items[j] = items[j+1];
}
items[count-1].n = front.n;
r--;
}
while ( r < 0 ) // rotate negatively.
{
if ( i == top+1 )
{
front.n = items[top+1].n;
items[top+1].n = items[count-1].n; // switch last with first
}
back.n = items[++i].n; // second element is the new back
items[i].n = front.n;
if ( i == bottom )
{
items[count-1].n = front.n; // last is first
i = 0;
r++;
continue;
}
else
{
front.n = items[++i].n;
items[i].n = back.n;
if ( i == bottom )
{
i = 0;
r++;
continue;
}
}
}
}
Instead of moving all the items in your stack, you could change the definition of 'beginning'. Have an index that represents the first item in the stack, 0 at the start, which you add to and subtract from using modular arithmetic whenever you want to rotate your stack.
Note that if you take this approach you shouldn't give users of your class access to the underlying array (not that you really should anyway...).
Well, as this is an abstraction around an array, you can store the "zero" index as a member of the abstraction, and index into the array based on this abstract notion of the first element. Roughly...
class WrappedArray
{
int length;
int first;
T *array;
T get(int index)
{
return array[(first + index) % length];
}
int rotateForwards()
{
first++;
if (first == length)
first = 0;
}
}
You've gotten a couple of reasonable answers, already, but perhaps one more won't hurt. My first reaction would be to make your stack a wrapper around an std::deque, in which case moving an element from one end to the other is cheap (O(1)).
What you are after here is a circular list.
If you insist on storing items in an array just use top offset and size for access. This approach makes inserting elements after you reached allocated size expensive though (re-allocation, copying). This can be solved by using doubly-linked list (ala std::list) and an iterator, but arbitrary access into the stack will be O(n).
The function rotate below is based on reminders (do you mean this under the 'mod' operation?)
It is also quite efficient.
// Helper function.
// Finds GCD.
// See http://en.wikipedia.org/wiki/Euclidean_algorithm#Implementations
int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);}
// Number of assignments of elements in algo is
// equal to (items.size() + gcd(items.size(),r)).
void rotate(std::vector<int>& items, int r) {
int size = (int)items.size();
if (size <= 1) return; // nothing to do
r = (r % size + size) % size; // fits r into [0..size)
int num_cycles = gcd(size, r);
for (int first_index = 0; first_index < num_cycles; ++first_index) {
int mem = items[first_index]; // assignment of items elements
int index = (first_index + r) % size, index_prev = first_index;
while (index != first_index) {
items[index_prev] = items[index]; // assignment of items elements
index_prev = index;
index = (index + r) % size;
};
items[index_prev] = mem; // assignment of items elements
}
}
Of course if it is appropriate for you to change data structure as described in other answers, you can obtain more efficient solution.
And now, the usual "it's already in Boost" answer: There is a Boost.CircularBuffer
If for some reason you'd prefer to perform actual physical rotation of array elements, you might find several alternative solutions in "Programming Pearls" by Jon Bentley (Column 2, 2.3 The Power of Primitives). Actually a Web search for Rotating Algorithms 'Programming Pearls' will tell you everything. The literal approach you are using now has very little practical value.
If you'd prefer to try to solve it yourself, it might help to try looking at the problem differently. You see, "rotating an array" is really the same thing as "swapping two unequal parts of an array". Thinking about this problem in the latter terms might lead you to new solutions :)
For example,
Reversal Approach. Reverse the order of the elements in the entire array. Then reverse the two parts independently. You are done.
For example, let's say we want to rotate abcdefg right by 2
abcdefg -> reverse the whole -> gfedcba -> reverse the two parts -> fgabcde
P.S. Slides for that chapter of "Programming Pearls". Note that in Bentley's experiments the above algorithm proves to be quite efficient (among the three tested).
I don't understand what the variables front and back mean, and why you need .n. Anyway, this is the shortest code I know to rotate the elements of an array, which can also be found in Bentley's book.
#include <algorithm>
std::reverse(array , array + r );
std::reverse(array + r, array + size);
std::reverse(array , array + size);
Related
I've been assigned this question for my lab (and yes I understand there will be backlash because it's homework). I've been working on this question for a couple of days to no avail and I feel like I'm missing something glaringly obvious.
My code:
int processSuitors(vector<int>& currentSuitors, list<int>& rekt)
{
int sizeSuitors = currentSuitors.size();
int eliminated = 2;
while(sizeSuitors != 1)
{
rekt.push_back(currentSuitors[eliminated]);
currentSuitors.erase(currentSuitors.begin() + eliminated);
sizeSuitors--;
if(eliminated > sizeSuitors)
{
eliminated -= sizeSuitors;
}
}
return currentSuitors[0];
}
Prompt:
In an ancient land, the beautiful princess Eve had many suitors. She decided on the following procedure to determine which suitor she would marry. First, all of the suitors would be lined up one after the other and be assigned numbers. The first suitor would be number 1, the second number 2, and so on up to the last suitor, number n. Starting at the first suitor she would then count three suitors down the line (because of the three letters in her name) and the third suitor would be eliminated from winning her hand and he would be removed from the line. Eve would then continue, counting three more suitors and eliminating every third suitor. When she reached the end of the line she would continue counting from the beginning.
Write a function named processSuitors that takes as arguments an STL vector of type int containing the suitors, and an STL list of type int that will collect all the suitors that are eliminated. The function returns an int storing the position a suitor should stand in to marry the princess if there are n suitors. The function that calls processSuitors will send the vector already filled with n suitors (1, 2, 3... n), and an empty list that needs to be filled with the position number of the suitors that were eliminated, in the order they were eliminated.
Restrictions: You may not create any containers (no arrays, no vectors, etc.); you need to use the vector and the list that are passed as parameters.
Use ONLY the following STL functions:
vector::size
vector::erase
vector::begin
ist::push_back
vector::operator[ ]
The adjacent files are hidden since we are to rely on what is given. Any clean-up of my code would be extremely appreciated as well.
What do you think of this solution.
Keep another vector that marks whether an index in your currentSuitors vector has been removed. Then have a helper function that will always find the next free index.
Instead of trying to reduce currentSuitors, you just keep marking elements in the taken list.
size_t findNextFreeSlot(const vector<bool>& taken, size_t pos)
{
// increment to the next candidate position
pos = (pos + 1) % taken.size();
// search for the first free slot
for (size_t i = 0; i < taken.size(); i++)
{
if (taken[pos] == false)
{
return next;
}
pos = (pos + 1) % taken.size();
}
// assert(false); // we should never get here as long as there's one free slot index in taken
return -1;
}
int processSuitors(vector<int>& currentSuitors, list<int>& rekt)
{
size_t len = currentSuitors.size();
vector<bool> taken(len); // keep a vector of eliminated indices from current
size_t index = len; // initialize one past the last valid element
size_t eliminated = 0;
if (len == 0)
{
return -1;
}
while (eliminated < (len-1))
{
// advance the index three times to the next "untaken" index
index = findNextFreeSlot(taken, index);
index = findNextFreeSlot(taken, index);
index = findNextFreeSlot(taken, index);
taken[index] = true; // claim this index as taken
rekt.push_back(currentSuitors[index]); // add the value at this index to the eliminated list
eliminated++;
}
index = findNextFreeSlot(taken, index); // find the last free index
return currentSuitors[index];
}
I have an array of values e.g. 1, 4, 7, 2.
I also have another array of values and I want to add its values to this first array, but only when they all are different from all values that are already in this array. How can I check it? I've tried many types of loops, but I always ended with an iteration problem.
Could you please tell me how to solve this problem? I code in c++.
int array1[7] = {2,3,7,1,0};
int val1 = rand() % 10;
int val2 = rand() % 10;
int array2[2] = {val1, val2};
and I am trying to put every value from array2 into array1. I tried loop
for (int x:array2)
{
while((val1 && val2) == x)
{
val1 = rand() % 10;
val2 = rand() % 10;
}
}
and many more, but still cannot figure it out. I have this problem because I may have various number of elements for array2. So it makes this "&&" solution infinite.
It is just a sample to show it more clearly, my code has much more lines.
Okay, you have a few problems here. If I understand the problem, here's what you want:
A. You have array1 already populated with several values but with space at the end.
1. How do you identify the number of entries in the array already versus the extras?
B. You have a second array you made from two random values. No problem.
You want to append the values from B to A.
2. If initial length of A plus initial length of B is greater than total space allocated for A, you have a new problem.
Now, other people will tell you to use the standard template library, but if you're having problems at this level, you should know how to do this yourself without the extra help from a confusing library. So this is one solution.
class MyArray {
public:
int * data;
int count;
int allocated;
MyArray() : data(nullptr), count(0), allocated(0) {}
~MyArray() { if (data != nullptr) free(data); }
// Appends value to the list, making more space if necessary
void add(int value) {
if (count >= allocated) {
// Not enough space, so make some.
allocated += 10;
data = (data == nullptr) malloc(allocated * sizeof(int))
: realloc)data, allocated * sizeof(int));
}
data[count++] = value;
}
// Adds value only if not already present.
void addUnique(int value) {
if (indexOf(value) < 0) {
add(value);
}
}
// Returns the index of the value, if found, else -1
int indexOf(int value) {
for (int index = 0; index < count; ++index) {
if (data[index] == value) {
return index;
}
}
return -1;
}
}
This class provides you a dynamic array of integers. It's REALLY basic, but it teaches you the basics. It helps you understand about allocation / reallocating space using old-style C-style malloc/realloc/free. It's the sort of code I was writing back in the 80s.
Now, your main code:
MyArray array;
array.add(2);
array.add(3);
array.add(7);
// etc. Yes, you could write a better initializer, but this is easy to understand
MyArray newValues;
newValues.add(rand() % 10);
newValues.add(rand() % 10);
for (int index = 0; index < newValues.count; ++index) {
array.addUnique(newValues.data[index]);
}
Done.
The key part of this is the addUnique function, which simply checks first whether the value you're adding already is in the array. If not, it appends the value to the array and keeps track of the new count.
Ultimately, when using integer arrays like this instead of the fancier classes available in C++, you HAVE TO keep track of the size of the array yourself. There is no magic .length method on int[]. You can use some magic value that indicates the end of the list, if you want. Or you can do what I did and keep two values, one that holds the current length and one that holds the amount of space you've allocated.
With programming, there are always multiple ways to do this.
Now, this is a lot of code. Using standard libraries, you can reduce all of this to about 4 or 5 lines of code. But you're not ready for that, and you need to understand what's going on under the hood. Don't use the fancy libraries until you can do it manually. That's my belief.
I finally determined that this function is responsible for the majority of my bottleneck issues. I think its because of the massively excessive random access that happens when most of the synapses are already active. Basically, as the title says, I need to somehow optimize the algorithm so that I'm not randomly checking a ton of active elements before landing on one of the few that are left.
Also, I included the whole function in case of other flaws that can be spotted.
void NetClass::Explore(vector <synapse> & synapses, int & n_syns) //add new synapses
{
int size = synapses.size();
assert(n_syns <= size );
//Increase the age of each active synapse by 1
Age_Increment(synapses);
//make sure there is at least one inactive vector left
if(n_syns == size)
return;
//stochastically decide whether a new connection is added
if((rand_r(seedp) %1000) < ( x / (1 +(n_syns * ( y / 100)))))
{
n_syns++; //a new synapse has been created
//main inefficiency here
while(1)
{
int syn = rand_r(seedp) % (size);
if (!synapses[syn].active)
{
synapses[syn].active = true;
synapses[syn].weight = .04 + (float (rand_r(seedp) % 17) / 100);
break;
}
}
}
}
void NetClass::Age_Increment(vector <synapse> & synapses)
{
for(int q=0, int size = synapses.size(); q < size; q++)
if(synapses[q].active)
synapses[q].age++;
}
Pass a random number, k, in the range [0, size-n_syns) to Age_Increment. Have Age_Increment return the kth empty slot.
Since you're already traversing the whole list in Age_Increment, update that function to return the list of the indexes of inactive synapses.
You can then pick a random item from that list directly.
This is similar to the problem of finding free blocks in memory management, so I would take a look at algorithms used in that domain, specifically free lists, which is a list of free positions. (These are usually implemented as linked lists to be able to pop elements off an end efficiently. Random access in a linked list would still be O(n) - with a smaller n, but still not the best choice for your use case.)
Trying not to lose it here. As you can see below I have assigned intFrontPtr to point to the first cell in the array. And intBackPtr to point to the last cell in the array...:
bool quack::popFront(int& nPopFront)
{
nPopFront = items[top+1].n;
if ( count >= maxSize ) return false;
else
{
items[0].n = nPopFront;
intFrontPtr = &items[0].n;
intBackPtr = &items[count-1].n;
}
for (int temp; intFrontPtr < intBackPtr ;)
{
++intFrontPtr;
temp = *intFrontPtr;
*intFrontPtr = temp;
}
return true;
}
In the else statement I'm simply reassigning to ensure that my ptrs are where I want them. For some reason I'm popping off the back instead of off the front.
Anyone care to explain?
I'm not entirely sure I understand what you're trying to do, but if I;m guessing right you're trying to 'pop' the 1st element of the array (items[0]) into the nPopFront int reference, then move all the subsequent elements of the array over by one so that the 1st element is replaced by the 2nd, the 2nd by the 3rd, and so on. After this operation, the array will contain one less total number of elements.
Not having the full declaration of the quack class makes most of the following guesswork, but here goes:
I'm assuming that item[0] represents the 'front' of your array (so it's the element you want 'popped').
I'm also assuming that 'count` is the number of valid elements (so item[count-1] is the last valid element, or the 'back' of the array).
Given these assumptions, I'm honestly not sure what top is supposed to represent (so I might be entirely wrong on these guesses).
Problem #1: your nPopFront assignment is reversed, it should be:
nPopFront = items[0].n;
Problem #2; your for loop is a big no-op. It walks through the array assigning elements back to their original location. I think you want it to look more like:
for (int i = 1; i < count; ++i)
{
items[i-1].n = items[i].n; // move elements from back to front
}
Finally, you'll want to adjust count (and probably top - if you need it at all) before you return to adjust the new number of elements in the data structure. The whole thing might look like:
bool quack::popFront(int& nPopFront)
{
if ( count >= maxSize ) return false;
if ( count == 0 ) return false; // nothing to pop
nPopFront = items[0].n;
intFrontPtr = &items[0].n; // do we really need to maintain these pointers?
intBackPtr = &items[count-1].n;
for (int i = 1; i < count; ++i)
{
items[i-1].n = items[i].n; // move elements from back to front
}
count -= 1; // one less item in the array
return true;
}
The original question seems to be that you don't understand why the function popFront returns 3 times when there are 3 elements?
If that's the case, I think you are missing the point of recursion.
When you make a recursive call, you are calling the same function again, basically creating a new stack frame and jumping back to the same function. So if there are 3 elements, it will recurse by encountering the first element, encountering the second element, encountering the third element, returning from the third encounter, returning from the second encounter, and returning from the first encounter (assuming you are properly consuming your array, which you don't appear to be).
The current function cannot return until the recursive call has iterated, thus it may appear to return from the last element before the second, and the second before the first.
That is how recursion works.
I wasn't able to make sense of your example, so I whipped one up real fast:
#include <iostream>
using namespace std;
bool popfront(int* ptr_, int* back_) {
cerr << ptr_[0] << endl;
if(ptr_ != back_) {
popfront(++ptr_, back_);
}
return true;
}
int main() {
int ar[4] = {4,3,2,1};
popfront(ar, ar + 3);
return 0;
}
That's not great, but it should get the point across.
Can't you just use a std::list?
That makes it really to pop from either end using pop_front or pop_back. You can also add to the front and the back. It also has the advantage that after popping from the front (or even removing from the middle of the list) you don't have to shift anything around (The link is simply removed) which makes it much more efficient than what you are, seemingly, proposing.
I'm assuming you're trying to assign the popped value to nPopFront?
bool stack::popFront(int& nPopFront)
{
//items[4] = {4,3,2,1}
if ( intFrontPtr < intBackPtr )
{
nPopFront = *intFrontPtr;
++intFrontPtr;
}
return true;
}
bool quack::popFront(int& nPopFront)
{
if(items.n==0) throw WhateverYouUseToSignalError;
nPopFront = items[0];
for (int =0;i<items.n-1,++i){
items[i]=items[i+1]
}
//update size of items array
}
I thought i'd post a little of my homework assignment. Im so lost in it. I just have to be really efficient. Without using any stls, boosts and the like. By this post, I was hoping that someone could help me figure it out.
bool stack::pushFront(const int nPushFront)
{
if ( count == maxSize ) // indicates a full array
{
return false;
}
else if ( count <= 0 )
{
count++;
items[top+1].n = nPushFront;
return true;
}
++count;
for ( int i = 0; i < count - 1; i++ )
{
intBackPtr = intFrontPtr;
intBackPtr++;
*intBackPtr = *intFrontPtr;
}
items[top+1].n = nPushFront;
return true;
}
I just cannot figure out for the life of me to do this correctly! I hope im doing this right, what with the pointers and all
int *intFrontPtr = &items[0].n;
int *intBackPtr = &items[capacity-1].n;
Im trying to think of this pushFront method like shifting an array to the right by 'n' units...I can only seem to do that in an array that is full. Can someone out their please help me?
Firstly, I'm not sure why you have the line else if ( count <= 0 ) - the count of items in your stack should never be below 0.
Usually, you would implement a stack not by pushing to the front, but pushing and popping from the back. So rather than moving everything along, as it looks like you're doing, just store a pointer to where the last element is, and insert just after that, and pop from there. When you push, just increment that pointer, and when you pop, decrement it (you don't even have to delete it). If that pointer is at the end of your array, you're full (so you don't even have to store a count value). And if it's at the start, then it's empty.
Edit
If you're after a queue, look into Circular Queues. That's typically how you'd implement one in an array. Alternatively, rather than using an array, try a Linked List - that lets it be arbitrarily big (the only limit is your computer's memory).
You don't need any pointers to shift an array. Just use simple for statement:
int *a; // Your array
int count; // Elements count in array
int length; // Length of array (maxSize)
bool pushFront(const int nPushFront)
{
if (count == length) return false;
for (int i = count - 1; i >= 0; --i)
Swap(a[i], a[i + 1]);
a[0] = nPushFront; ++count;
return true;
}
Without doing your homework for you let me see if I can give you some hints. Implementing a deque (double ended queue) is really quite easy if you can get your head around a few concepts.
Firstly, it is key to note that since we will be popping off the front and/or back in order to efficiently code an algorithm which uses contiguous storage we need to be able to pop front/back without shifting the entire array (what you currently do). A much better and in my mind simpler way is to track the front AND the back of the relevant data within your deque.
As a simple example of the above concept consider a static (cannot grow) deque of size 10:
class Deque
{
public:
Deque()
: front(0)
, count(0) {}
private:
size_t front;
size_t count;
enum {
MAXSIZE = 10
};
int data[MAXSIZE];
};
You can of course implement this and allow it to grow in size etc. But for simplicity I'm leaving all that out. Now to allow a user to add to the deque:
void Deque::push_back(int value)
{
if(count>=MAXSIZE)
throw std::runtime_error("Deque full!");
data[(front+count)%MAXSIZE] = value;
count++;
}
And to pop off the back:
int Deque::pop_back()
{
if(count==0)
throw std::runtime_error("Deque empty! Cannot pop!");
int value = data[(front+(--count))%MAXSIZE];
return value;
}
Now the key thing to observe in the above functions is how we are accessing the data within the array. By modding with MAXSIZE we ensure that we are not accessing out of bounds, and that we are hitting the right value. Also as the value of front changes (due to push_front, pop_front) the modulus operator ensures that wrap around is dealt with appropriately. I'll show you how to do push_front, you can figure out pop_front for yourself:
void Deque::push_front(int value)
{
if(count>=MAXSIZE)
throw std::runtime_error("Deque full!");
// Determine where front should now be.
if (front==0)
front = MAXSIZE-1;
else
--front;
data[front] = value;
++count;
}