I am self-studying java. I have been studying data structures for the past couple of days. I am reading the book "Data Structures and Algorithms in Java". there is an exercise that I have problem with. it asks for implementing the pop method with recursion so that when the method is called it should delete all the items at once. can anyone help on this? a pointer on how to do it would be much appreciated. thanks. (following is the pop method currently implemented).
public double pop() // take item from top of stack
{
return stackArray[top--]; // access item, decrement top
}
First IMO you should understand how to implement a non-recursive counterpart of this method.
It can be something like this:
public void popAll() {
while(!stack.isEmpty()) {
stack.pop();
}
}
Once you understand this, the recursive version should be easy:
public void popAllRecursive() {
if(stack.isEmpty()) {
//nothing to remove, return
return;
}
stack.pop(); // remove one stack element
popAllRecursive(); // recursive invocation of your method
}
Since its an exercise I just provide you an idea and leave the implementation to you (you can consider to provide the method in class Stack and use the top counter and stackArray - an implementation of your stack.
Hope this helps
You need to think about the base case where there is nothing in the stack, i.e. stack.pop() == null.
For the recursive case, it is quite intuitive as you just need to recursively call pop() until the base case is met.
Call pop() repeatedly till end of stack.
As you have not mentioned how the data is stored cant help you providing code.
thanks every one, i solved the problem. don't know if efficient, but i did like below:
public void pop()
{
if(isEmpty()){
return;
}
if (top>=0){
stackArray[top] = stackArray[top--];
pop();
}
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
So basically my code iterates through the list and the original method is supposed to return the linked list however it doesn't seem to be adding the nodes that I link in the recursive method and I'm confused as to why. Can anyone help me?
// Append MyStringBuilder2 b to the end of the current MyStringBuilder2, and
// return the current MyStringBuilder2. Be careful for special cases!
public MyStringBuilder2 append(MyStringBuilder2 b)
{
//Test if Invalid
if(b.firstC==null){
return this;
}
//Test if condition is met
else {
CNode lastNode =firstC;
recurseAppendBuild(lastNode, b);
return this;
}
}
private void recurseAppendBuild(CNode lastNode, MyStringBuilder2 BPoint) {
//Test if all nodes have been added
if(lastNode.next==null&&BPoint.firstC==null) {
System.out.println("finished");
}
//Tests if all nodes in the original linked list have been passed through
else if(lastNode.next==null) {
lastNode.next= new CNode(BPoint.firstC.data);
BPoint.firstC=BPoint.firstC.next;
recurseAppendBuild(lastNode.next, BPoint);
}
//Recurse until condition is met
else {
recurseAppendBuild(lastNode.next, BPoint);
}
}
```
Okay, your code needs some work. Let's look at your first method. I'm going to rewrite it.
public MyStringBuilder2 append(MyStringBuilder2 fromBuilder)
{
if (fromBuilder.firstC != null) {
recurseAppendBuild(fromBuilder.firstC);
}
return this;
}
I changed a number of things.
I used a more meaningful name on the argument. It's a good idea to give your variables meaningful names, not just 'b'. Note that I never use one-character names. If nothing else, it can be really hard to search on that. If you do "int i" and then search for i, you'll get a LOT of hits that aren't i at all.
This is a very trivial thing and doesn't affect the quality of your code.
In all cases, you always return yourself, so the return statement can be after the if-else structure, which is easier to see that it's the same.
That eliminates the top if-block entirely, so I reversed the logic.
And I changed the method signature of your recursive method, for reasons I'll describe below.
The end result is short and sweet and easily understood.
Now, let's look at your second method:
private void recurseAppendBuild(CNode lastNode, MyStringBuilder2 BPoint) {
//Test if all nodes have been added
if(lastNode.next==null&&BPoint.firstC==null) {
System.out.println("finished");
}
//Tests if all nodes in the original linked list have been passed through
else if(lastNode.next==null) {
lastNode.next= new CNode(BPoint.firstC.data);
BPoint.firstC=BPoint.firstC.next;
recurseAppendBuild(lastNode.next, BPoint);
}
//Recurse until condition is met
else {
recurseAppendBuild(lastNode.next, BPoint);
}
}
Your variable named BPoint breaks JAVA naming standards. It should start with a lower case letter.
If you pass in a MyStringBuilder2 as the second argument, then as you move things from BPoint to the end of your list and recurse, you have to remove them from BPoint, which is a pain in the ass. So instead, I didn't point to the wrapper. In my code above, I passed in the head of the list (fromBuilder.firstC).
You are finished when your list-to-append-from (BPoint) is empty, not when lastNode is null. Your first if is flawed.
You aren't recursively adding items. You're recursively looking for the end of the list. I don't think that's what you really want.
You're messing up the integrity of BPoint. You're making a copy of the nodes as you add them, but you're then dropping the old ones from BPoint but NOT maintaining lastC at all.
And you have a significant problem if your list starts as empty, as firstC and lastNode will both be empty.
So let's think about it this way. First, doing this recursively is silly, but that's the assignment, so we'll work with it.
A recursive definition is:
AppendedList = OriginalList + firstItem + Append Tail of List.
private void recurseAppendBuild(CNode headToAppend) {
if (headToAppend == NULL) {
// All done.
return;
}
CNode nodeToAppend = new CNode(headToAppend.data);
if (lastC == nullptr) {
// Original list is empty.
firstC = lastC = nodeToAppend;
else {
lastC.next = nodeToAppend;
lastC = nodeToAppend; // Point the tail at the new tail
}
// And here you recurse, always.
recurseAppendBuild(headToAppend.next);
}
Let's look at this.
I'm assuming you keep both a firstC and lastC in your builder. It would be deeply inefficient otherwise. So you only need to pass in the chain of nodes, not the surrounding wrapper.
By putting a null-check at the top of this method, you eliminate other null checks. Note -- this means we can eliminate the null check in the first method.
Create the new copy right away. That part's easy, right?
If lastC is null, you have an empty list, so you just point both front and back of the list to your new node.
Otherwise you point the old tail's next pointer to your new node and update the tail pointer to remain pointed at the tail.
Either way, you can safely recurse with the next object in the original list.
Advantages of this method, aside from working, is that you don't destroy the original list, and it's pretty clear to read.
I am trying to find the square of a number using the scanner method but keep getting a
stackflow error. I am new to programming will be glad if someone helps me out.
My code is as below
import java.util.Scanner;
interface Number {
int findSqr(int i); // Returns the square of n
}
//a class A which implements the interface Number.
class A implements Number {
public int findSqr(int i) {
return findSqr(i);
}
}
public class Question5_1{
public static void main (String[] args){
A a = new A(); // an object of class A
// Reading a number from the keyboard
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
System.out.print(a.findSqr(i));
}
}
Fix the line which invokes the function recursively return findSqr(i) with return i * i as follows --
public int findSqr(int i) {
return i * i;
}
What you did there is an infinite recursion. The bit where it says
public int findScr(int i) {
return findSqr(i)
}
essentially calls the very same method an infinite number of times in the return statement.
What happens is, that you execute the method, and it tries to return an integer. What you wrote though is a return statement that "returns" another call of the same method, so it gets executed again. Then the whole thing starts over again, so you get a StackOverflow.
Since there is no other code present, I have no idea what you are actually trying to do, but the return findSqr(i) line is what causes the problem.
Initially, recursion may be a rather complicated subject to really wrap you head around, I suggest you either avoid it for now (although it enables you to solve many problems in a really elegant way) or try to understand it a bit better maybe. I'd suggest the Wikipedia article about recursion, although it gets complicated quite fast, or any other tutorial on it, just look it up on Google.
I'm currently working on a small graph theory algorithm, which uses a recursive Depth-First Search.
Since it's recursive, I'm asking myself, if I should use the Stream API to perform such a task or use Iterators and for each Loops.
This is my code:
private void processNext(Node node) {
//METHOD A
for (Node neighbour : node) {
if (!connectedNodes.contains(neighbour)) {
connectedNodes.add(neighbour);
processNext(neighbour);
}
}
//OR METHOD B
node.getNodes().stream().filter(not(connectedNodes::contains)).forEach(e -> {
connectedNodes.add(e);
processNext(e);
});
//OR METHOD C
node.getNodes().stream().forEach(e -> {
if (!connectedNodes.contains(e)) {
connectedNodes.add(e);
processNext(e);
}
});
}
Method A and C will work 100% intended, but I'm not sure about B...
Does the filter method in the streaming API filter non matching objects out before foreach or while foreach? (Do B and C the exact same thing?)
And which Method will be the fastest?
Any help is apreciated!
OK Method B and C work exactly the same!
Not sure if the iterator way is faster, but since B requires less space, I'm going for that one!
import java.util.ArrayDeque;
class Main {
public static void main(String[] args) {
ArrayDeque<Integer> arrayDeque = new ArrayDeque<>();
arrayDeque.push(10);
arrayDeque.push(11);
arrayDeque.push(15);
arrayDeque.push(20);
arrayDeque.push(200);
arrayDeque.add(700);
while (arrayDeque.peek() != null) {
System.out.println(arrayDeque.pop() + " ");
}
}
}
Good Day .. I have a question regarding the peek() method in ArrayDeque Class .. all the method will do is retrieve the head of the arrayDeque without removing it. so if that is the case how it's working perfectly without going for an infinite loop .. I mean who told the Method to look for the Next element after each complete loop.
There is no infinite loop because the condition in the whole loop will be false when the queue is empty.
while (arrayDeque.peek() != null)
When pop removes the last element, arrayDeque.peek() will return null and that's the end.
That is probably why I prefer to check for isEmpty().
This makes it easier to grasp that you need to pop elements off the queue or it will never go emtpy.
while (!arrayDeque.isEmpty()) { arrayDeque.pop(); }
I'm developing a Java application that uses Kahlua for embedded Lua scripting. After calling a lot of functions it always crashes with a stack overflow... is there something I need to do to remove unused call frames from the stack?
In standard Lua, you can use the lua_pop function to remove items from the Lua stack. See this answer for hints on this usage.
If you are calling your code repeatedly, the easiest thing to do is store the height of the stack before the processing and restore it afterwards:
int top = lua_gettop(L);
... /* some processing involving the stack*/
lua_settop(L, top);
Now, I'm not sure how to achieve this in Kahlua. But in the source I see LuaCallFrame.getTop() and LuaCallFrame.setTop() so the code should be similar.
If you're using the Kahlua framework correctly, the stack should automatically get cleaned up when returning from a function. If this is not so, you've found a bug, and I would very much like a bug report on it :)
Best would a (close to) minimal testcase which exposes the problem.
You have to make sure you return out of every method call. For example:
...main(...){
displayMenu();
}
void displayMenu(){
System.out.println("1.Do A. \n2.Do B");
int q = readInt;
if (q==1){
doA();
}else{
doB();
}
}
void doA(){
.....
displayMenu()
}
void doB(){
....
displayMenu();
}
A way to make the stack not blow up is to do something like this:
...main(...){
while(true){displayMenu()};
}
void displayMenu(){
System.out.println("1.Do A. \n2.Do B");
int q = readInt;
if (q==1){
doA();
}else{
doB();
}
}
void doA(){
.....
}
void doB(){
....
}
This way all the calls return back to the base level.
Try and use tail calls where you can, they don't take up a stack slot:
function foo ( )
return bar()
end