I'm currently trying to use a function that compares the left and right side character to return a true or false Boolean value as to whether the string entered by the user is a palindrome or not, but I get a vague error statement to do with line 44. Not sure how to proceed. I am a beginner-level Java programmer who is open-minded and willing to learn, so don't roast me to hard haha.
import java.util.Scanner;
/**
*
* #author owner
*/
public class Q2_RecursivePalidrome {
public static void main(String[] args) {
int leftSideCharacter = 0;
int rightSideCharacter = 0;
Scanner scan = new Scanner (System.in);
System.out.println("Enter word to check whether palidrome: ");
String userInput = scan.next();
char[] checkPalidrome = userInput.toCharArray(); // creates an array of characters
System.out.println(isPalidrome(checkPalidrome, leftSideCharacter, rightSideCharacter));
}
public static boolean isPalidrome(char[] checkPalidrome, int leftSideCharacter, int rightSideCharacter) {
leftSideCharacter = 0;
rightSideCharacter = checkPalidrome.length - 1; // java arrays start at 0, not 1.
if (rightSideCharacter > leftSideCharacter) { // check both ends of string character by character
// to be palidrome, both sides of string should be same
//
if (checkPalidrome[leftSideCharacter] == checkPalidrome[rightSideCharacter]) {
return (isPalidrome(checkPalidrome, leftSideCharacter + 1, rightSideCharacter - 1));
}
else {
return false;
}
}
return true;
}
}
There are a couple main issues here, but you have the right idea:
Your recursive function uses left and right indices to determine which characters to compare in the test string. However, these two pointers are immediately set to the left and right ends of the string when the function is called, so they never recursively move towards the middle. Since the base case where the indices are equal is unreachable, the stack overflows. Remember, these calls are identical all the way down the stack, but with different parameters, so one-time "set up" tasks like setting initial indices should be moved outside of the recursive function.
Your initial pointer indices are 0, 0. This is an inaccurate "set up" call to the recursive function--it should be 0, string.length - 1.
Here is code that fixes these problems and cleans up comments and variable names:
import java.util.*;
public class Q2_RecursivePalidrome {
public static void main(String[] args) {
String test = "racecar";
System.out.println(isPalidrome(test.toCharArray(), 0, test.length() - 1));
}
static boolean isPalidrome(char[] test, int l, int r) {
if (l < r) {
if (test[l] == test[r]) {
return isPalidrome(test, l + 1, r - 1);
}
else {
return false;
}
}
return true;
}
}
By the way, the important lesson to take from all this is how to debug your program. In this case, printing your indices (the arguments that change from one call to the next) at the top of your recursive function will clearly show that they aren't doing what you expect.
Related
I've written a recursive program in java that takes an array of characters and with two methods, one switching places of the two leftmost tiles and the other moving the rightmost tile to the left of the leftmost tile. It then returns the order of moves which makes the array in alphabetical order with the smallest number of moves. It seems to be working but I'm also supposed to set a max depth (15), and what I wonder is what do I return when it has reached max depth? It seems to be working right now, but I'm not sure it's correct.
This is part of the code:
public static String Sorter(char[] letters){
int nrOfMoves = 0;
return Sorter(letters,nrOfMoves);
}
private static String Sorter(char[] letters, int nrOfMoves){
if(sorted(letters)) return "";
if(nrOfMoves >= 15) return "" ; //??
switchLeft(letters);
String moveb = "b" + Sorter(letters,nrOfMoves+1);
switchLeft(letters);
rightToLeft(letters);
String moves = "s" + Sorter(letters,nrOfMoves+1);
leftToRight(letters);
if(moves.length()<moveb.length()) return moves;
return moveb;
}
The example seems fine. Personally, I would make use of nrOfMoves++ instead of nrOfMoves+1
and I would have it count down (number of moves left instead of number of moves performed). This makes sure that your Sorter method does not need to know at what depth it needs to stop. It just gets a limit of how many more recursions it can perform
public static String Sorter(char[] letters){
int nrOfMoves = 15;
return Sorter(letters,nrOfMoves);
}
private static String Sorter(char[] letters, int nrOfMoves){
if(sorted(letters) || nrOfMoves <= 0){
return "";
}
switchLeft(letters);
String moveb = "b" + Sorter(letters,nrOfMoves--);
switchLeft(letters);
rightToLeft(letters);
String moves = "s" + Sorter(letters,nrOfMoves--);
leftToRight(letters);
if(moves.length()<moveb.length()) return moves;
return moveb;
}
I want to know how recursive method work to prints a large X composed of smaller X's with a given “width”, input number, which is guaranteed to be odd.
the “width” is length (number) of X’s along one line large X.
Example for an X of width input number =3
the method will print this shape!
X X
X
X X
I try to solve this problem but I couldn't
can anyone here help me ..
in java code ,
This is my code he works good but prints wrong when numberinput=7 or 5
public static String shape(String i,int numberinput) {
//error check, not working for even numbers
if(numberinput%2 == 0)
return null;
//terminating condition, stop recursion when this occurs.
if(numberinput == 1)
return "X";
else
return "X"+" "+i+"\n" +" "+shape(" "+i,numberinput-2)+" "+"\n"+i+" "+"X";
}
he prints this when numberinput=5
X X
X X
X
X X
X X
A valid recursive method should have two parts.
Recursive call (call itself to do part of work)
Terminating condition (A condition to stop the recursion)
You have a recursive call, but not a termination condition. Hence your recursion won't stop until it fills up the entire stack and cause an exception. Hence you should include a terminating condition in your recursive method.
A sample implementation might look like this.
public static String shap(String i, int numberinput) {
//error check, not working for even numbers
if(numberinput%2 == 0)
return null;
//terminating condition, stop recursion when this occurs.
if(numberinput == 1)
return "X";
//recursion, call recursive until terminating condition occurs.
return "X" + i + shap(i, numberinput-2) + i + "X";
}
I have written a java code, in which recursion is only for the levels, to generate the string i have used a loop :
import java.util.*;
import java.lang.*;
import java.io.*;
public class Main
{
public static void main (String[] args) throws java.lang.Exception
{
List<String> ans = new ArrayList<String>();
shap(7, 1, ans);
//System.out.println(ans);
for(int i = 0;i < ans.size();i++){
System.out.println(ans.get(i));
}
}
public static void shap(int numberinput, int currentLevel, List<String> ans) {
if(currentLevel == numberinput+1) return;
String val = "";
for(int i = 1;i <= numberinput;i++){
if(i == currentLevel || i == (numberinput+1-currentLevel)) val += "X";
else val += " ";
}
ans.add(val);
shap(numberinput, currentLevel+1, ans);//Recursion step for the levels
}
}
Link to solution on Ideone : http://ideone.com/RioL9g
I'm trying to use this code to implement a Priority Queue. There are a number of questions regarding this implementation on the site, but given how many different ways you can write code to do essentially the same thing I am still at a loss after looking through a handful of other examples.
There are some missing lines in this code, but I am limited to editing only the four marked lines and so I find myself stuck on one particular aspect. I can't seem to understand how 'quantity' is incremented.
From my understanding main creates a new object of maxSize = 5. Then calls the insertItem method passing the value of 130. This should be placed into the root (I had put queArray[quantity] = item; into the first blank) at which point the insertItem method exits and is then called again with the next value. So at what point is 'quantity' incremented? Maybe I am missing something incredibly simple, or maybe there is another way of solving this that may not be apparent or known to beginners like me?
I would think you would want to increment quantity under the initial if statement, but that doesn't seem to be an option, so as far as I can tell the else statement can never be executed as quantity doesn't change. I know I am incorrect, but I don't know how, some help would be greatly appreciated.
public class Main {
/**
* #param args the command line arguments
*/
// array in sorted order, from max at 0 to min at size-1
private int maxSize;
private long[] queArray;
private int quantity;
public Main(int s) {
maxSize = s;
queArray = new long[maxSize];
quantity = 0;
}
public void insertItem(long item) {
int i;
if (quantity == 0)
__________; // insert at 0
else
{
for (i = quantity - 1; i >= 0; i--) // start at end,
{
if (item > queArray[i]) // if new item larger,
__________; // shift upward
else
// if smaller,
break; // done shifting
}
__________; // insert it
__________;
} // end else (quantity > 0)
}
public boolean PQEmpty(){
return (quantity == 0);
}
public long removeItemPQ(){
return queArray[--quantity];
}
public long peekMin(){
return queArray[quantity - 1];
}
public static void main(String[] args) {
Main thePQ = new Main(5);
thePQ.insertItem(130);
thePQ.insertItem(450);
thePQ.insertItem(110);
thePQ.insertItem(430);
thePQ.insertItem(280);
while (!thePQ.PQEmpty()) {
long item = thePQ.removeItemPQ();
System.out.print(item + " ");
}
System.out.println("");
}
}
It isn't a style I'd recommend, but you could use queArray[quantity++] = item;.
I am currently learning the basics of Java from a book and I've got this code as an example of Nested Loops using Recursion. I understand everything, but the usage of return function in the end of the code. I cannot figure out how the program decide, when to stop exactly when K=4. I've tried to debug it and this continued to be like a mystery for me. Here is the code :
import java.util.Scanner;
public class nestedLoops {
public static int numberOfLoops;
public static int numberOfIterations;
public static int[] loops;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("N = ");
numberOfLoops = input.nextInt();
System.out.print("K = ");
numberOfIterations = input.nextInt();
input.close();
loops = new int[numberOfLoops];
nestedLoops(0);
}
public static void nestedLoops(int currentLoop) {
if (currentLoop == numberOfLoops) {
printLoops();
return;
}
for (int counter=1;counter<=numberOfIterations;counter++) {
loops[currentLoop] = counter;
nestedLoops(currentLoop + 1);
}
}
public static void printLoops() {
for (int i = 0; i < numberOfLoops; i++) {
System.out.printf("%d ", loops[i]);
}
System.out.println();
}
}
It would be very helpful if someone explain me how return works in this particular example in the end when numbers are "4.4" and also how it works at all in a void method, because I've been searching for explanation of that but did not succeed...
Thank you beforehand !
A return statement in a void method stops running the method and returns back to the calling code. In this example with the input:
numberOfLoops = 4
numberOfIterations = 4
Right after taking the input, you create an array based off of the input and then call the nestedLoops(0) method:
public static void nestedLoops(int currentLoop) {
if (currentLoop == numberOfLoops) {
printLoops();
return;
}
for (int counter=1;counter<=numberOfIterations;counter++) {
loops[currentLoop] = counter;
nestedLoops(currentLoop + 1);
}
}
The explanation
For starts, let's just ignore the for loop. The if statement checks to see if currentLoop == numberOfLoops and it does this every time this method is called. Right now currentLoop is 0 (the value we passed into this method when we called it) and numberOfLoops is 4 (the value we entered at the very beginning) so this is false and none of the code inside is called.
The for loop below the if statement is going to run numberOfIterations times. In our case, this loop is going to run 4 times. I will write out what happens below in sequential order:
- input is 4, 4
- nestedLoops(0) called- currentLoop = 0
- if evaluates to false
- for loop runs
- loops[0] = 1
- nestedLoops(1)
- if evaluates to false ( 1 != 4)
- for loop runs
- loops[1] = 1
- nestedLoops(2)
- if evaluates to false (2 != 4)
- for loop runs
- loops[2] = 1
- nestedLoops(3)
- if evaluates to false (3 != 4)
- for loop runs
- loops[3] = 1
- nestedLoops(4)
- if evaluates to TRUE (4 == 4)
- loops are printed (all values are 1 right now)
-returns to calling location
-Which is the for loop associated with this indention.
-For loop increments, and then sets loops[3] = 2.
- then this loop finishes
- then this loop finishes
etc. etc.
The return in a void method just means "okay, stop what you're doing and go back to who/whatever called this and move on" In this case its jumping back to previous for loop to keep working.
The for loop inside the nestedLoops method is calling itself numberOfIterations times. So it goes 0, then makes numberOfIterations calls. So if you entered 4 you would see 4 calls with currentLoop=1 then 16 calls with currentLoop=2 and so on....
When all else fails write some code to debug your code. I am a visual person myself so making some output helps when the debugger doing it for me.
public static HashMap<Integer, Integer> map = new HashMap();
public static void main(String[] args) {
....
System.out.println(map);
}
public static void nestedLoops(int currentLoop) {
if(map.containsKey(currentLoop)) {
map.put(currentLoop, map.get(currentLoop)+1);
} else {
map.put(currentLoop, 1);
}
...
}
I am creating a stock exchange type program and so far I've got the input working so that it takes the command from the user properly. However what it does to the input isn't working as expected. The first thing I am confused on is why it is throwing me a NullPointerException when I run the code.
Basically the program will take an input of 3 things followed by whitespace between them. So for instance I want to buy 30 shares at $20 each, I would type the input like the following:
b 30 20
It would then split it into 3 parts and store it into an array. After that it will compare the first index of the array to see what the program should do, in this example it will buy so it will invoke the buy method and store the share amount and share value into my CircularArrayQueue.
It gets the share value and share amount stored into a Node, but when I try to invoke the enqueue method with my CirularArrayQueue to store the Node into the Queue, it gives me a NullPointerException.
Another issue I've been running into was the termination for the program. The program is supposed to terminate when it sees that the first index value of the input is "q". I've made a while loop stating that it will loop when the boolean quit is false. Then within the while loop I've made an if statement checking to see if the value of stockParts[0] is "q". If so it would change the value of quit to be true so it can end the loop, but for some reason it isn't terminating and it is still looping.
I've been scratching my head on these issues for a couple hours but I cannot seem to find the root of the problem. Could someone please assist me on this? The following is the code from my main class and the CircularArrayQueue class:
import java.util.Scanner;
import java.lang.Integer;
public class StockTran {
String command = "";
String[] stockParts = null;
CircleArrayQueue Q;
boolean quit = false;
public StockTran(String inputCommand) {
try {
Scanner conReader = new Scanner(System.in);
this.command = inputCommand.toLowerCase();
this.stockParts = command.split("\\s"); // splits the input into three parts
buyShares(Integer.parseInt(stockParts[1]), Integer.parseInt(stockParts[2])); //testing purpose only
while (quit == false) {
if (this.stockParts[0] == "q") { // ends transaction and terminates program
System.out.println("Share trading successfully cancelled.");
quit = true;
}
if (this.stockParts == null || this.stockParts.length > 3) {
throw new Exception("Bad input.");
}
if (stockParts[0] == "b") { // checks to see if it is a buying of shares
int shares = Integer.parseInt(stockParts[1]); // stores share amount
int value = Integer.parseInt(stockParts[2]); // stores selling value
buyShares(shares, value); // calls buyShares method and adds share to queue
}
else if (stockParts[0] == "s") { // checks to see if it is a selling of shares
int shares = Integer.parseInt(stockParts[1]); // stores share amount
int value = Integer.parseInt(stockParts[2]); // stores selling value
sellShares(shares, value); // calls sellShares method
}
else if (stockParts[0] == "c") { // checks to see if it is capital gain
capitalGain(); // calls capitalGain and calculates net gain
}
System.out.println("Enter your next command or press 'q' to quit: ");
command = conReader.nextLine().toLowerCase();
stockParts = command.split("\\s");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void buyShares(int shareAmout, int shareValue) { // takes in share total and values for each share
Node temp = new Node(shareAmout, shareValue); // stores values into node
try {
Q.enqueue(temp); // enqueues the node into the CircularArrayQueue
//System.out.println(Q.toString());
} catch (FullQueueException e) {
e.printStackTrace();
}
}
public void sellShares(int shareAmount, int sharePrice) { // ToDo
}
public int capitalGain() { // ToDo
return 0;
}
public static void main(String[] args) {
String inputCommand = "";
Scanner mainReader = new Scanner(System.in);
System.out.println("Enter 'b' to purchase share, 's' to sell share, 'c' for capital gain, or 'Q' to quit: ");
inputCommand = mainReader.nextLine();
StockTran tran = new StockTran(inputCommand);
}
}
public class CircleArrayQueue implements Queue {
protected Node Q[]; // initializes an empty array for any element type
private int MAX_CAP = 0; // initializes the value for the maximum array capacity
private int f, r;
public CircleArrayQueue(int maxCap) {
MAX_CAP = maxCap;
Q = new Node[MAX_CAP]; // sets Q to be a specific maximum size specified
f = 0; // sets front value to be 0
r = 0; // sets rear value to be 0;
}
public int size() {
return (MAX_CAP - f + r) % MAX_CAP; // returns the size of the CircularArrayQueue
}
public boolean isEmpty() { // if front and rear are of equal value, Queue is empty
return f == r;
}
public Node front() throws EmptyQueueException { // method to get the front value of the CircularArrayQueue
if (isEmpty()) throw new EmptyQueueException("Queue is empty.");
return Q[f]; // returns object at front of CircularArrayQueue
}
public Node dequeue() throws EmptyQueueException { // method to remove from the front of the CircularArrayQueue
if (isEmpty()) throw new EmptyQueueException("Queue is empty.");
Node temp = Q[f]; // stores front object in local variable
Q[f] = null; // sets the value to be null in the array
f = (f + 1) % MAX_CAP; // sets the new front value to be this
return temp; // returns the object that was originally in the front
}
public void enqueue(Node element) throws FullQueueException { // method to add to the end of the CircualarArrayQueue
if (size() == MAX_CAP - 1) throw new FullQueueException("Queue has reached maximum capacity.");
Q[r] = element; // stores the new element at the rear of array
r = (r + 1) % MAX_CAP; // sets the new rear value to be the location after element insertion
}
}
You haven't initialized the reference Q. Since it's a field variable, it's initialized by default to null.
CircleArrayQueue Q;
When you're faced with a problem like this, you have to debug it. One source of information is the stack trace from the exception, which will tell you where the exception was thrown. You may also be able to ask the debugger in your development environment to stop automatically at the point an exception is thrown.
Secondly, when you compare strings in Java, use the equals() method rather than the == operator. The equals() method compares object values. The == operator compares the values of the references that point to the objects. You can have two equal objects with different reference values.
initialize your CircleArrayQueue Q. if you dont initialize it. it takes null as default value.
CircleArrayQueue q= new CircleArrayQueue(size);