I'd like to do the following:
std::stack <int> s;
int h = 0;
s.push(2);
h = s.pop();
Such as to have h hold the value 2. When I try my method, I get “void value not ignored as it ought to be”.
Is this not the intention of the .pop() method? What is the preferred way to do this?
The standard library containers separate top() and pop(): top() returns a reference to the top element, and pop() removes the top element. (And similarly for back()/pop_back() etc.).
There's a good reason for this separation, and not have pop remove the top element and return it: One guiding principle of C++ is that you don't pay for what you don't need. A single function would have no choice but to return the element by value, which may be undesired. Separating concerns gives the user the most flexibility in how to use the data structure. (See note #3 in the original STL documentation.)
(As a curiousum, you may notice that for a concurrent container, a pop-like function is actually forced to remove and return the top value atomically, since in a concurrent context, there is no such notion as "being on top" (or "being empty" for that matter). This is one of the obvious examples of how concurrent data structures take a significant performance hit in order to provide their guarantees.)
You can use:
h = s.top();
then after that use(if you want to remove the most recent value otherwise do nothing)
s.pop();
It works the same way!!
You can actually use s.top() to store the element and then pop it using
s.pop().
use
int h=s.top();
s.pop()
instead of
int h=s.pop()
You cannot directly assign s.pop() to some data type, as s.pop() removes element from stack and returns nothing.
S.pop() does not return any value. Because pop() is void function.
If you want to see the top of the stack then it will be S.top(). If you store this value then write value = S.top().
Related
I am programming a method called popButtom () in C ++ using stacks.
The method must do the following: ¨Eliminate the element of the base and leave the stack in the same order but without the element elminado¨, I can not use pop or push.
For example:
ini stack:
A
B
C
D
end stack:
A
B
C
I have programmed the following, but I do not know that I can have bad:
void popFull()
{
struct node *A, *B;
top1 = top;
while (top1 != NULL)
{
B = top1->ptr;
A = top1;
B->ptr = A;
top1 = B;
}
}
Regards
Mariam
So, I'll see what I can do to answer this, though it would be very helpful if you could include a more complete version of your code, because I'm not entirely sure what type of data structure some of your variables are because there are no declarations included. As well, could you clarify what you mean by "but I do not know that I can have bad:"? I think these changes would make your question easier to answer.
In any case, I'll try to answer your question by interpreting it as "How do I eliminate the element at the base and leave the stack in the same order, not using pop or push." (I assume this is some sort of assignment?)
To that end I'll propose several options. C++11 has another function that isn't push() or pop() which you can use by doing stack.emplace() which just adds an item to the top of the stack. It is functionally the same as stack.push but it might be a nice hack. It's obviously a bit of a technicality, and there actually is a difference (it's very nuanced though, here's a link if you're interested: C++: Stack's push() vs emplace()) but you might be able to get away with it.
Next, I'll say that if you cannot use stack.pop() or stack.push() this next option is a possibility, but only if you initialize stack with a container class of vector, because otherwise the items are not contiguous in memory and there is no guarantee that it will work. I'm referring to, of course, pointer arithmetic. Here: Copy std::stack into an std::vector is another answer that deals with this, but I'll give a brief overview of what they did. If you initialize your stack using a std::vector as in this example in the documention, you can then copy your stack to a vector, and then operate freely on that vector, then copy back to a stack.
Here's what I mean (keep in mind this only works if the container class is vector because it seem like you're just designing a function to take in an argument and not initialize your own).
//this is how it will have to have been initailized
//for this to be guarenteed to work
std::stack<int, std::vector<int>> myStack;
int* begin = &stack.top()+1;
int* end = being+stack.size();
std::vector stackContents(begin,end);
And hurray, smooth sailing from here, now you can remove the item freely using your method of choice on the vector. Then, when you've modified the vector, you can create another stack to return by doing the opposite:
std::stack<int, std::vector<int>> newStack (stackContents);
return newStack;
Obviously this is a major workaround, and in the real world pop() and push() are useful functions and are included for a reason. This might actually be a good time to touch on the idea that stacks are designed to be accessed from either end. That's why it's been categorized as Last In First Out, because the idea of order matters and trying to circumvent that order means that a stack wasn't the proper data structure to use in the first place. Either way, that's my two cents, and I hope this helps.
Can I use popFront() and then eventually push back what was poped? The number of calls to popFront() might be more than one (but not much greater than it, say < 10, if does matter). This is also the number of calls which the imaginary pushBack() function will be called too.
for example:
string s = "Hello, World!";
int n = 5;
foreach(i; 0 .. n) {
// do something with s.front
s.popFront();
}
if(some_condition) {
foreach(i; 0 .. n) {
s.pushBack();
}
}
writeln(s); // should output "Hello, World!" since number of poped is same as pushed back.
I think popFront() does use .ptr but I'm not sure if it in D does makes any difference and can help anyway to reach my goal easily (i.e, in D's way and not write my own with a Circular buffer or so).
A completely different approach to reach it is very welcome too.
A range is either generative (e.g. if it's a list of random numbers), or it's a view into a container. In neither case does it make sense to push anything onto it. As you call popFront, you're iterating through the list and shrinking your view of the container. If you think of a range being like two C++ iterators for a moment, and you have something like
struct IterRange(T)
{
#property bool empty() { return iter == end; }
#property T front() { return *iter; }
void popFront() { ++iter; }
private Iterator iter;
private Iterator end;
}
then it will be easier to understand. If you called popFront, it would move the iterator forward by one, thereby changing which element you're looking at, but you can't add elements in front of it. That would require doing something like an insertion on the container itself, and maybe the iterator or range could be used to tell the container where you want an alement inserted, but the iterator or range can't do that itself. The same goes if you have a generative range like
struct IncRange(T)
{
#property bool empty() { value == T.max; }
#property T front() { return value; }
void popFront() { ++value; }
private T value;
}
It keeps incrementing the value, and there is no container backing it. So, it doesn't even have anywhere that you could push a value onto.
Arrays are a little bit funny because they're ranges but they're also containers (sort of). They have range semantics when popping elements off of them or slicing them, but they don't own their own memory, and once you append to them, you can get a completely different chunk of memory with the same values. So, it is sort of a range that you can add and remove elements from - but you can't do it using the range API. So, you could do something like
str = newChar ~ str;
but that's not terribly efficient. You could make it more efficient by creating a new array at the target size and then filling in its elements rather than concatenating repeatedly, but regardless, pushing something on the the front of an array is not a particularly idiomatic or efficient thing to be doing.
Now, if what you're looking to do is just reset the range so that it once again refers to the elements that were popped off rather than really push elements onto it - that is, open up the window again so that it shows what it showed before - that's a bit different. It's still not supported by the range API at all (you can never unpop anything that was popped off). However, if the range that you're dealing with is a forward range (and arrays are), then you can save the range before you pop off the elements and then use that to restore the previous state. e.g.
string s = "Hello, World!";
int n = 5;
auto saved = s.save;
foreach(i; 0 .. n)
s.popFront();
if(some_condition)
s = saved;
So, you have to explicitly store the previous state yourself in order to restore it instead of having something like unpopFront, but having the range store that itself (as would be required for unpopFront) would be very inefficient in most cases (much is it might work in the iterator case if the range kept track of where the beginning of the container was).
No, there is no standard way to "unpop" a range or a string.
If you were to pass a slice of a string to a function:
fun(s[5..10]);
You'd expect that that function would only be able to see those 5 characters. If there was a way to "unpop" the slice, the function would be able to see the entire string.
Now, D is a system programming language, so expanding a slice is possible using pointer arithmetic and GC queries. But there is nothing in the standard library to do this for you.
Is this line valid in a program, which is using stack?
s1.top()==s2.push(j);
This shows that the value of the top element of a stack(s1) is assigned to another stack s2.
Where j='A';
If not, then what are the alternates to it?
This is not valid, because std::stack::push returns void
If you want to know if s1.top() is contained in s2, you should use std::find
No it is not valid, and definitely not how you describe. Looking at the documentation for stack in C++, method push has return type void (i.e. does not return anything).
Note that == is a comparison of two values, whereas = is an assignment (assign right hand side to left hand side).
To remove from top of stack s1 and push onto s2, you should do :
s2.push(s1.top());
s1.pop();
I have a global variable:
std::unordered_map<int, std::stack<int>> intTable;
To add to this, I do this currently: (I've seen C++11 initializer lists, but I'm not sure if I'll hit this Visual C++ 11 2013 bug --> http://connect.microsoft.com/VisualStudio/feedback/details/807966/initializer-lists-with-nested-dynamically-allocated-objects-causes-memory-leak)
std::stack<int> s;
s.push(10);
then I do
intTable[integerKey] = s;
I then need to add to the stack sometimes, and check its top value so, and if it is greater than a value, I need to pop it and erase the key from the map:
intTable[integerKey].push(20);
if (intTable[integerKey].top() >= someIntegerValue)
{
intTable[integerKey].pop();
if (intTable[integerKey]->size() == 0)
{
intTable.erase(integerKey);
}
}
My question is there a better way of doing this? For example one inefficieny I see is that I'm indexing into the map multiple times. Is it possible to avoid that? How can I store a reference to the intTable[integerKey] without copying it?
Map members are initialized with the default constructor when accessed.
std::stack<int> &localReference = intTable[integerKey];
Will allocate the stack (if it does not exist), and return a reference to the stack.
You can do
std::stack<int> &localReference = intTable[integerKey];
In beginning of your function and access local reference afterwards, although compiler will most likely optimize away intTable[integerKey] anyways within the scope of local function so it may be no difference in actual assembly code.
Unordered map access by key is really fast. You could take a reference to the element and work on that, but otherwise this is fine.
I'd like to do the following:
std::stack <int> s;
int h = 0;
s.push(2);
h = s.pop();
Such as to have h hold the value 2. When I try my method, I get “void value not ignored as it ought to be”.
Is this not the intention of the .pop() method? What is the preferred way to do this?
The standard library containers separate top() and pop(): top() returns a reference to the top element, and pop() removes the top element. (And similarly for back()/pop_back() etc.).
There's a good reason for this separation, and not have pop remove the top element and return it: One guiding principle of C++ is that you don't pay for what you don't need. A single function would have no choice but to return the element by value, which may be undesired. Separating concerns gives the user the most flexibility in how to use the data structure. (See note #3 in the original STL documentation.)
(As a curiousum, you may notice that for a concurrent container, a pop-like function is actually forced to remove and return the top value atomically, since in a concurrent context, there is no such notion as "being on top" (or "being empty" for that matter). This is one of the obvious examples of how concurrent data structures take a significant performance hit in order to provide their guarantees.)
You can use:
h = s.top();
then after that use(if you want to remove the most recent value otherwise do nothing)
s.pop();
It works the same way!!
You can actually use s.top() to store the element and then pop it using
s.pop().
use
int h=s.top();
s.pop()
instead of
int h=s.pop()
You cannot directly assign s.pop() to some data type, as s.pop() removes element from stack and returns nothing.
S.pop() does not return any value. Because pop() is void function.
If you want to see the top of the stack then it will be S.top(). If you store this value then write value = S.top().