I have to write the following recursion method:
public static int countA(String s)
Yet I find it impossible to do this without declaring a counter and position variable; like so:
public static int countA(String s, int position) {
int count = 0;
if( s.charAt(position) == 'A' )
count++;
if( position + 1 < s.length() ) {
count += countA(s, position + 1);
}
return count;
}
How can I simplify my answer so that my method is the same as the one listed?
EDIT: Yes, I want to count all A's inside a string.
Try this:
public static int countA(String s) {
int count = 0;
if (s == null)
return 0;
if (s.length() == 0)
return 0;
if (s.charAt(0) == 'A')
count++;
return count + countA(s.substring(1));
}
There are two forms of recursion,
Tail Recursion : The return value is calculated as a combination of the value of current subroutine and the return value of the next call. Example,
int factorial(int a) {
if(a==0)
return 1;
else
return a * factorial( a-1 );
}
Accumulator based recursion : You accumulate the results by adding an additional parameter and return the accumulated value.
int factorial(int a, int fact) {
if(a==0)
return fact;
else
return factorial(a-1, a*fact);
}
Obviously what you have here is accumulator based, while you can improve it to Tail recursion.
Tail recursion is considered more readable, while it can cause a StackOverflow! (no pun intended). This is because it has to push the current value to a stack, before calling subroutine again. And when you make a large number of such calls, this stack might go over its limit.
Some compilers optimize tail recursion to accumulator based in order to avoid this problem.
What about:
public static int countA(String s) {
if(s==null) return 0;
if(s.length()==0) return 0;
if( s.charAt(0) == 'A' )
{
return 1 + countA(s.substring(1));
} else
{
return countA(s.substring(1));
}
}
I think something like this should do the trick
Here we are assuming that countA returns the number of As inside String s
public static int countA(String s)
{
if(s.length()==0) return 0; // return 0 if string is empty
else
{
// if the first char is A add 1 to the answer, recurse
if(s.toCharArray()[0])=='A') return 1+countA(s.subString(1,s.length()));
// else add nothing to the answer, recurse
else return countA(s.subString(1,s.length()));
}
}
You move the position variable out of the method and make it static(since your countA() is also static).
static int position = 0;
public static int countA(String s) {
int count = 0;
if( s.charAt(position) == 'A' )
count++;
if( position + 1 < s.length() ) {
position++;
count += countA(s);
}
return count;
}
Ideally you have the termination condition first, which then usually simplifies the code by reducing indentation/nesting and have a "do nothing" action for it (typically requiring one more iteration than absolutely required).
You also don't need the local variable!
public static int countA(String s, int position) {
if (position == s.length())
return 0;
return (s.charAt(position) == 'A' ? 1 : 0) + countA(s, position + 1);
}
Related
Write a method to find the position of a given element in a stack counting from the top of the stack. More precisely,
the method should return 0 if the element occurs on the top, 1 if there is another element on top of it, and so on. If
the element occurs several times, the topmost position should be returned. If the element doesn’t occur at all, -1
must be returned.
You are asked to write this method in two different ways; one way is to implement it internally inside the
ArrayStack class and the other way is to implement it externally in a separate class. Important: At the end
the stack should be returned to the original state (i.e. no elements should be removed and the order of the elements
should not change).
This is the externall class
public class Stack{
public static int searchstack(ArrayStack z, int n) {
ArrayStack temp = new ArrayStack(z.size());
int c = 0;
boolean flag = false;
while (!z.isEmpty()) {
if (z.top() == n) {
flag = true;
return c;
}
if (z.top() != n) {
temp.push(z.pop());
c++;
flag = false;
}
}
if (flag == false) {
c = -1;
}
while (!temp.isEmpty() && !z.isFull()) {
z.push(temp.pop());
}
return c;
}
public static void main(String[] args) {
ArrayStack z = new ArrayStack(4);
z.push(3); // first element
z.push(7);// 2nd
z.push(8);// 3rd
z.push(1);// 4th
z.printStack();
int n = 3;
System.out.println("Searching externally for" + " " + n + " " + searchstack(z, n));
System.out.println("Searching internally for" +" "+n+" "+ z.searchfor(n)+" "); //THE ERROR IS HERE
}
}
And this is the ArrayClass
public class ArrayStack {
private int[] theStack;
private int maxSize;
private int top;
public ArrayStack(int s) {
maxSize = s;
theStack = new int[maxSize];
top = -1;
}
public void push(int elem) {
top++;
theStack[top] = elem;
}
public int pop() {
int result = theStack[top];
top--;
return result;
}
public int top() {
return theStack[top];
}
public boolean isFull() {
return (top == (maxSize - 1));
}
public boolean isEmpty() {
return (top == -1);
}
public int size() {
return (top + 1);
}
//HERE IS THE METHOD I IMPLEMENTED INTERNALLY AND CALL IT AT THE STACK CLASS
public int searchfor(int n) {
for (int i = top; i >= 0; i--) {
if (theStack[top] == n) {
return i;
}
}
return -1;
}
public void printStack() {
if (top == -1)
System.out.println("Stack is empty!!\n");
else {
System.out.println(theStack[top] + " <- top");
for (int i = top - 1; i >= 0; i--)
System.out.println(theStack[i]);
System.out.println();
}
}
}
The error appearing at the Stack class is at the last line of calling the searchfor method implemented in the Arraystack class , error says that there is no method implemented in Arraystack with the name searchfor (); thiugh I did implement it .whatseems to be the problem ?
You have a bug in your searchStack() implementation. You are losing elements if you find the one you are looking for and it isn't the topmost one.
How to fix your searchStack() method:
keep popping z until you have an empty ArrayStack. While doing so, add the value to a queue.
create valIndex and assign it -1.
Then go through the queue and remove the items from it and adding them to z. While doing so, check for the last occurence of the desired value and save it in valIndex.
if valIndex equals -1 return it. Else, use following equation to convert it to correct index and return:
valIndex = (z.size - 1) - valIndex
So I have the majority of the code written and it works. Except for the iterative method keeps showing that it is not a palindrome regardless of what is typed in. I am at a loss as to how to remedy it here is the code.
//David Crouse Assignment 2
import java.util.Scanner;
public class Assignment2 {
public static boolean loop = false;
//main
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Welcome to the Palindrome Checker!");
do{
System.out.print("Enter a string to check if it is a palindrome. ");
System.out.print("Enter x to exit.");
String word = input.nextLine();
word = word.replaceAll("\\s","");
word = word.toLowerCase();
//Exit Program
if(word.equalsIgnoreCase("x")){
System.out.println("End of program. Good Bye!");
System.exit(0);
}
if(iterativePalindromeChecker(word)){
System.out.println("Iterative Result: Palindrome!");
}else{
System.out.println("Iterative Result: Not a palindrome");
}
if(recursivePalindromeChecker(word)){
System.out.println("Recursive Result: Palindrome!\n");
}else{
System.out.println("Recursive Result: Not a palindrome\n");
}
loop = true;
}while (loop == true);
}
//Iterative Method
public static boolean iterativePalindromeChecker(String str){
boolean result = false;
int length = str.length();
int i, begin, end, middle;
begin = 0;
end = length - 1;
middle = (begin + end)/2;
for (i = begin; i <= middle; i++) {
if (str.charAt(begin) == str.charAt(end)) {
begin++;
end--;
}
else {
break;
}
}
if (i == middle + 1) {
result = false;
}
return result;
}
//Recusive Methods
public static boolean recursivePalindromeChecker(String str){
if(str.length() == 0 || str.length() == 1)
return true;
if(str.charAt(0) == str.charAt(str.length()-1))
return recursivePalindromeChecker(str.substring(1,str.length()-1));
return false;
}
}
Your iterative method never sets result to be true. Here's a modified version:
public static boolean iterativePalindromeChecker(String str){
int length = str.length();
int i, begin, end, middle;
begin = 0;
end = length - 1;
middle = (begin + end)/2;
for (i = begin; i <= middle; i++) {
if (str.charAt(begin) == str.charAt(end)) {
begin++;
end--;
}
else {
return false;
}
}
return true;
}
Your iterative method does not set result = true anywhere, so it really can't help it. Although I think the iterative method could be better overall. Take a close look at what is happening in the recursive one and see if you can implement some of it (like the guard conditions) more closely in the iterative method, and keep in mind that you are not limited to a single index value in a for loop either. e.g.:
public static boolean iterativePalindromeChecker(String str) {
for(int start = 0, end = str.length() - 1; start < end; start++, end--) {
if(str.charAt(start) != str.charAt(end)) {
return false;
}
}
return true;
}
I'm guessing someone once told you that a function should only have one return point, and trying to follow that led you to using a mutable result variable which screwed you here. Using break poses the same ostensible problem anyway. Save yourself the headache and just return as soon as you know the answer.
public static boolean iterativePalindromeChecker(String str) {
int begin = 0;
int end = str.length() - 1;
while (begin < end) {
if (str.charAt(begin) != str.charAt(end)) {
return false;
}
begin++;
end--;
}
return true;
}
I am trying to find the first occurrence of a letter in a string. For example, p in apple should return 1. Here is what I have:
// Returns the index of the of the character ch
public static int indexOf(char ch, String str) {
if (str == null || str.equals("")) {
return -1;
} else if(ch == str.charAt(0)) {
return 1+ indexOf(ch, str.substring(1));
}
return indexOf(ch, str.substring(1));
}
It just doesn't seem to be returning the correct value.
I'll give you some hints:
When you've found the letter, you don't need to recurse further. Additionally, think about what you should be returning in this case.
When do you recurse, also think about what the function should return.
Is there anything special you need to do if the recursive call returns -1?
Your attempt was good, but not quite there. Here is a correct implementation based off yours:
public static int indexOf(char ch, String str) {
// Returns the index of the of the character ch
if (str == null || str.equals("")) {
// base case: no more string to search; return -1
return -1;
} else if (ch == str.charAt(0)) {
// base case: ch is at the beginning of str; return 0
return 0;
}
// recursive step
int subIndex = indexOf(ch, str.substring(1));
return subIndex == -1 ? -1 : 1 + subIndex;
}
There were two problems with your attempt:
In the else if part, you had found the character, so the right thing to do was stop the recursion, but you were continuing it.
In your last return statement, you needed to be adding 1 to the recursive call (if the character was eventually found), as a way of accumulating the total index number.
Here's another variation. Instead of calling substring you could modify the function a bit to pass the next index to check. Notice that the recursion is initiated with index 0. (You could actually start on any index. There is also some error checking in case the letter isn't found. Looking for x in apple will return -1.)
public static void main(String []args){
System.out.println("Index: " + indexOf('e', "apple", 0));
System.out.println("Index: " + indexOf('x', "apple", 0));
System.out.println("Index: " + indexOf('p', "Mississippi", 3));
System.out.println("Index: " + indexOf('p', "Mississippi", 908));
}
public static int indexOf(char ch, String str, int idx) {
// check for garbage data and incorrect indices
if (str == null || str.equals("") || idx > str.length()-1)
return -1;
// check to see if we meet our condition
if (ch == str.charAt(idx))
return idx;
// we don't match so we recurse to check the next character
return indexOf(ch, str, idx+1);
}
Output:
Index: 4
Index: -1
Index: 8
Index: -1
Well if we must use recursion then try this:
class RecursiveFirstIndexOf {
public static void main(String[] args) {
System.out.println(indexOf('p', "apple", 0));
}
static int indexOf(char c, String str, int currentIdx) {
if (str == null || str.trim().isEmpty()) {
return -1;
}
return str.charAt(0) == c ? currentIdx : indexOf(c, str.substring(1), ++currentIdx);
}}
Why not doing it straight forward?
public static void main(String[] args) {
String str = "abcdef";
for (int idx = 0; idx < str.length(); idx++) {
System.out.printf("Expected %d, found %d\n", idx, indexOf(str.charAt(idx), str, 0));
}
System.out.printf("Expected -1, found %d\n", indexOf(str.charAt(0), null, 0));
}
public static int indexOf(char ch, String str, int index) {
if (str == null || index >= str.length()) return -1;
return str.charAt(index) == ch ? index : indexOf(ch, str, ++index);
}
OUTPUT:
Expected 0, found 0
Expected 1, found 1
Expected 2, found 2
Expected 3, found 3
Expected 4, found 4
Expected 5, found 5
Expected -1, found -1
first of all : Recursion has two pillars, Base Case and General Case.
Base Case (the termination point) is the one where Recursion terminates and General Case as the name implies is where the program keeps executing until it finds Base Case
you may try this example, where count is a global static variable
public static int indexOf(char ch, String str)
{
// Returns the index of the of the character ch
if (str == null || str.Equals("")) //Base Case
{
if (count != 0)
{
if(str.Length == 0)
return -1;
return count;
}
else
return -1;
}
else if (ch == str.CharAt(0)) //Base Case
return 1 + count;
count++;
return indexOf(ch, str.Substring(1)); //General Case
}
Here's the deal I want to count the recursive calls for a basic Fibonacci code. I already have it so the values will print out in column format but I don't know how to update the recCounter. I think I have to add recCounter++; Somewhere and I don't know where
public static int recursionFibonacci(int n) {
recCounter = 1;
return fibonacci1(n);
}
public static int fibonacci1(int n) {
if (n == 1 || n == 2) {
return 1;
} else {
return fibonacci1(n-1) + fibonacci1(n-2);
}
}
You should increment the counter every time you call the function:
public static int fibonacci1(int n) {
recCounter++; // <<-- here
if (n == 1 || n == 2) {
return 1;
} else {
return fibonacci1(n-1) + fibonacci1(n-2);
}
}
I am very close to finishing my one practice problem that deals with a palindrome and a string parameter and I am stuck with the main method to call the method. Every time I compile my code it compiles, but then when I go to input data, it keeps on running and does not give me a result. Can anyone aid in me in what I need to do to get it to return the result? The problem just asks to create a method that checks if it is a palindrome, my main method to test it is what is giving me trouble.
This is my code:
import java.util.*;
public class TestisPalindrome
{
public static boolean isPalindrome(String str) {
int left = 0;
int right = str.length() -1;
while(left < right) {
if(str.charAt(left) != str.charAt(right)) {
return false;
}
}
left ++;
right --;
return true;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter a string to see if it is a palindrome or not: ");
String st1 = scan.nextLine();
System.out.println(isPalindrome(st1));
}
}
right & left increment should be in while loop
while(left < right)
{
if(str.charAt(left) != str.charAt(right))
{
return false;
}
left ++;
right --;
}
You've created an infinite loop. You have a while loop, but never change the conditions.
while(left < right)
{
if(str.charAt(left) != str.charAt(right))
{
return false;
}
}
Assuming left < right when you start, this will never change.
You have lines to increment left and right, but your code will never reach those lines, since it never gets out of the while loop.
You are overthinking this. Look at StringBuffer:
StringBuffer input = new StringBuffer(str);
return str.equals(input.reverse()).toString);
Please note that there is a performance impact of your implementation:
while(left < right) { //multiply inner operations by n/2
if(str.charAt(left) != str.charAt(right)) { //three operations
return false;
}
//This need to be inside your while loop
left ++; //one operation
right --; //one operation
}
This leads to an O(n) = (n * 5) / 2. On the other hand, if you simply reverse a string, it's only O(n) = n in the worst case. This is not a significant impact, but can add up depending on how you're accessing this.
You can also solve it like this:
public static boolean isPalindrome (String str){
String convertedStr = "";
for (int i = 0; i <str.length(); i++){
if (Character.isLetterOrDigit(str.charAt(i)))
convertedStr += Character.toLowerCase(str.charAt(i));
}
if (convertedStr.equals(reverseString(convertedStr)))
return true;
else
return false;
} //End of isPalindrome
Here is the code I used to determine whether a string is Palindrome String or not:
private static boolean isPalindromeString(String str){
if (str == null)
return false;
int len = str.length();
for (int i=0; i<len/2 ; i++){
if (str.charAt(i) != str.charAt(len - i - 1)){
return false;
}
}
return true;
}
I hope this can help you.