Need help converting iterative process to recursive - java

I am trying to convert the following iterative code:
int rows = 3;
for (int i = 0; i <= rows; i++)
{
for (int j = 0; j < i; j++)
{
System.out.print("*");
}
for (int j = 0; j < rows-i; j++)
{
System.out.print("-");
}
System.out.println();
}
with the output:
---
*--
**-
***
to recursive code. This is for an assignment. I created the iterative code in hopes of being able to figure out how to directly convert it to recursive. Here's my effort of that:
public void stringY(int star, int count){
if (star > 0){
System.out.print("*");
stringY(star - 1, count);
}
}
public void stringX(int dash,int count){
if (dash == -1) {
return;
}else if (dash < count){
System.out.print("-");
stringX(dash - 1, count);
} else if (dash == count){
stringX(dash - 1, count);
}
}
public void printPattern(int n) {
if (n == -1){
return;
} else {
printPattern(n-1);
stringY(n, n);
stringX(n, n);
System.out.println();
}
}
My issue here is that while I get the output I am looking for with regard to the "*" part of the pattern, I have absolutely no clue how to get the "-" part of the pattern. Now being that this is an assignment I don't want any solutions, but any pointers in the right direction are absolutely welcome. I should note that my two requirements are: 1) I have to complete my assignment entirely without using loops and 2) I can use as many helper methods as I need, but the main calling method (printPattern) must stay public void and must continue to only accept integers. Further clarification: The other two methods in the recursive code block are helper methods I created.

First let m = number of '*' to print and let n = number of '-' to print
For each recursion, increment m by 1 and decrement n by 1.
public static void main(String[] args) {
printPattern(3);
}
public static void printPattern(int n) {
printing(n, n);
}
//Variable size basically represent the number of columns
public static void printing(int n, int size) {
//stop condition
if(n == -1)
return;
//m is the number of * to print
int m = size - n;
printAsterisk(m);
//n is the number of - to print
printHyphen(n);
System.out.println();
printing(n - 1, size);
}
public static void printAsterisk(int m) {
if(m == 0)
return;
System.out.print('*');
printAsterisk(m - 1);
}
public static void printHyphen(int n) {
if(n == 0)
return;
System.out.print('-');
printHyphen(n - 1);
}

Think of it this way, they are all just loops doing some work. All you need is theoretically one recursive function that calls itself till the passed value.
void loop(int i, int till, Worker doThis) {
if (i>=till) return;
doThis.work(i);
loop(i+1, till, doThis);
}
Worker is just an interface,
public interface Worker {
void work(int index);
}
Now we need to pass the work that needs to be done. There are three loops, hence three calls to the loop function.
final int rows = 3;
// outer loop
loop(0, rows+1, new Worker() {
public void work(int index) {
// Stars
loop(0, index, new Worker() {
public void work(int index) {
System.out.print("*");
}
});
// Dashes
loop(0, rows-index, new Worker() {
public void work(int index) {
System.out.print("-");
}
});
System.out.println();
}
});

I would start by extracting then STAR and DASH,
private static final String DASH = "-";
private static final String STAR = "*";
Next, I would write a method to repeat a String a given number of times. Also, I would use a StringBuilder (here I've done it recursively)
private static StringBuilder repeat(StringBuilder sb, String str, int n) {
if (n > 0) {
sb.append(str);
repeat(sb, str, n - 1);
}
return sb;
}
Next, a private recursive method to print the pattern based on StringBuilder
private static void printPattern(StringBuilder sb, int s) {
System.out.println(sb);
int p = sb.indexOf(DASH, s);
if (p > -1) {
sb.replace(p, p + DASH.length(), STAR);
printPattern(sb, s + STAR.length());
}
}
And finally the public method
public static void printPattern(int n) {
printPattern(repeat(new StringBuilder(), DASH, n), 0);
}

Related

CountZeroes in java

I don't know where am I going wrong. I want to count zeroes via recursion but I am not getting it:
public class countzeroes {
public static int countZerosRec(int input){
int count=0;
return countZerosRec(input,count);
}
private static int countZerosRec(int input ,int count){
if (input<0) {
return -1;
}
if(input==0) {
return 1;
}
int m = input%10;
input = input/10;
if(m==0){
count++;
}
countZerosRec(input,count);
return count;
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int n = s.nextInt();
System.out.println(countZerosRec(n));
}
}
Put return count in if(input == 0) statement and instead of
countZerosRec(input, count); return count; put return countZerosRec(input, count);.
The correct method would be:
public class countzeroes {
private static int countZerosRec(int input){
if (input<0) {
return -1;
}
if (input==0) {
return 1;
}
if(input < 10) {
return 0;
}
int m = (input%10 == 0)? 1: 0;
input = input/10;
return m + countZerosRec(input);
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int n = s.nextInt();
System.out.println(countZerosRec(n));
}
}
Let me explain 2 problems in your code:
1- First of all, your second if statement (if(input == 0)) ruin everything. Consider 1200100 as an example. In the 6th round of recursion the input would be 1, and if you divide it on 10 the result is 0 (which is the input of next recursion round) and therefore all the answers would be 1.
2- Secondly, it would be nice if you don't change the input parameter in your code. because it's completely error-prone (In complicated codes, you can not trace the changes happen on a parameter and it makes debugging hard). So, I just removed the count parameter from the input.
And finally, It is better to name your classes in CamelCase form. (CountZeroes)
Change your method as below. Return count always
private static int countZerosRec(int input ,int count){
if (input <= 0) { // check if input is negative or zero
return count;
}
int m = input % 10;
input = input / 10;
if (m == 0) {
count++; // increment if current digit is zero
}
return countZerosRec(input,count);
}
public static int zeroCount(int num)
{
if(num == 0)
return 0;
if(num %10 ==0)
return 1 + zeroCount(num / 10);
else
return zeroCount(num/10);
}
this would work
You can use Streams:
System.out.println("11020304".chars().filter(c -> c == '0').count());
Result: 3
Your count logic is excellent.
in below line ... you are making logic mistake.. just fix it.
private static int countZerosRec(int input, int count) {
if (input < 0) {
return -1;
}
if (input == 0) {
return count;
//return 1; /// you need to change your code here, in last its getting zero as (num < 10 )/10 is 0
// its entering here everytime, and returning one.
// since its the base condition to exit the recursion.
// for special case of 0 (zero) count, handle your logic when it is //returned.
//...... rest of your code
}

how to count many times a character occurs in a string without using s loop

the code below is meant to count each time character 'x' occurs in a string but it only counts once ..
I do not want to use a loop.
public class recursionJava
{
public static void main(String args[])
{
String names = "xxhixx";
int result = number(names);
System.out.println("number of x: " + result);
}
public static int number (String name)
{
int index = 0, result = 0;
if(name.charAt(index) == 'x')
{
result++;
}
else
{
result = result;
}
index++;
if (name.trim().length() != 0)
{
number(name);
}
return result;
}
}
You could do a replacement/removal of the character and then compare the length of the resulting string:
String names = "xxhixx";
int numX = names.length() - names.replace("x", "").length(); // numX == 4
If you don't want to use a loop, you can use recursion:
public static int number (String name)
{
if (name.length () == 0)
return 0;
int count = name.charAt(0)=='x' ? 1 : 0;
return count + number(name.substring(1));
}
As of Java 8 you can use streams:
"xxhixx".chars().filter(c -> ((char)c)=='x').count()
Previous recursive answer (from Eran) is correct, although it has quadratic complexity in new java versions (substring copies string internally). It can be linear one:
public static int number(String names, int position) {
if (position >= names.length()) {
return 0;
}
int count = number(names, position + 1);
if ('x' == names.charAt(position)) {
count++;
}
return count;
}
Your code does not work because of two things:
Every time you're calling your recursive method number(), you're setting your variables index and result back to zero. So, the program will always be stuck on the first letter and also reset the record of the number of x's it has found so far.
Also, name.trim() is pretty much useless here, because this method only removes whitespace characters such as space, tab etc.
You can solve both of these problems by
making index and result global variables and
using index to check whether or not you have reached the end of the String.
So in the end, a slightly modified (and working) Version of your code would look like this:
public class recursionJava {
private static int index = 0;
private static int result = 0;
public static void main(String[] args) {
String names = "xxhixx";
int result = number(names);
System.out.println("number of x: " + result);
}
public static int number (String name){
if(name.charAt(index) == 'x')
result++;
index++;
if(name.length() - index > 0)
number(name);
return result;
}
}
You can use StringUtils.countMatches
StringUtils.countMatches(name, "x");

java : Inverted string triangle using recursion?

I'm trying to write a method that accept a string and print an
inverted triangle from it. For example, if I had
trianglePrint("abcdefgh"), the output would be
abcdefgh
abcfgh
abgh
ab
It kinda of works...it's just that I'm getting the following errors
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
-1 at Triangle.trianglePrint(Triangle.java:39) at Triangle.trianglePrint(Triangle.java:43) at
Triangle.trianglePrint(Triangle.java:43) at
Triangle.trianglePrint(Triangle.java:43) at
Triangle.trianglePrint(Triangle.java:43) at
Triangle.trianglePrint(Triangle.java:17) at
Triangle.main(Triangle.java:6)
Any suggestions on what I'm doing wrong? Suggestions on a more
efficient way to code this, will be appreciated too.
public class Triangle
{
public static void main(String[] args)
{
trianglePrint("abcdefgh");
}
public static void trianglePrint(String string)
{
int length,terms ;
length =string.length() ;
if (length%2==0)
terms = (length/2);
else
terms = (length/2) +1 ;
trianglePrint(string,terms,length);
}
public static void trianglePrint(String string,int terms,int length)
{
String [] Array = new String [terms];
int padterm= length ;
/*if (length%2==0)
terms = (length/2);
else
terms = (length/2) +1 ;
*/
if (terms == 1)
if (length%2==0)
Array[0]=pad(string.substring(0,2),padterm) ;
else
Array[0]=pad(string.substring(0,1),padterm) ;
else
Array[terms-1]=pad((string.substring(0, terms)
+string.substring(length-terms)),padterm);
//use to monitor value of term
System.out.println(terms);
//used to monitor actual array content
System.out.println(Array[terms-1]);
trianglePrint(string,(terms-1),length);
}
public static void printList(String[] list,int position)
{
if (position < list.length)
System.out.println(list[position]);
printList(list,position+1);
}
//pads with appropriate spaces
public static String pad(String string,int length)
{
String result ;
if (string.length() >= length)
result = string ;
else
result = pad(" "+ string+" " ,length);
return result ;
}
}
You need a condition to stop the recursion. If terms is 0, then Array[terms-1] will cause Exception, like:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at Triangle.trianglePrint(Triangle.java:46)
So when variable temrs becomes 0, we need to stop recursion. You can add the following code to trianglePrint method, which will make your program work.
if(0 == terms)
{
return;
}
Change
public static void trianglePrint(String string,int terms,int length)
{
to
public static void trianglePrint(String string,int terms,int length)
{
if(0 == terms)
{
return;
}
Output in console;
4
abcdefgh
3
abcfgh
2
abgh
1
ab
I wrote new code to solve the problem for you, using recursion. I believe it is both shorter and more efficient than your existing solution. An assumption goes into this: the strings have an even number of digits (you didn't explain how to handle odd number of digits)
public static void solve(String word) {
solve(word, 0);
}
public static void solve(String word, int it) {
// print starting spaces
for(int i = 0; i < it; i++)
System.out.print(" ");
// print out string
System.out.print(word);
// print new line
System.out.println();
if(word.length() > 2) {
int newlengthperside = (word.length() - 2)/2;
solve( word.substring(0, newlengthperside) + word.substring(word.length() - newlengthperside), it+1);
}
}
To understand this code, first look at the main method. We have a for loop that prints out a certain number of spaces before the string, based on the variable passed to the method, then we print out the string, then we print out a new line. Afterwards, we determine if the length of the string is not finished yet, and we take the left side and the right side of the new string, and call the method again. This recursion will terminate once the string has less than or equal to 2 characters.
We also make the method easy to use by overloading the method with another solve that just takes in a word, and calls the main solve method with that word and 0, the number of spaces to initially print.
Your algorithm (as I understand it), seems to simplify into this
public static void trianglePrint(String in,
int offset) {
if (offset >= in.length()) { // Terminating condition.
return;
}
StringBuilder sb = new StringBuilder(offset); // For padding.
for (int i = 0; i < offset; i++) {
sb.append(' ');
}
final String padding = sb.toString(); // This is the padding, so don't clear.
sb.append(in); // Add the current input.
sb.append(padding); // Add more "invisible" padding.
System.out.println(sb.toString()); // print it.
int left = in.length() / 2; // One half.
String lh = in.substring(0, left - 1); // the left.
String rh = in.substring(left + 1, in.length()); // the right.
trianglePrint(lh + rh, offset + 1); // recurse.
}
public static void trianglePrint(String in) {
trianglePrint(in, 0);
}
You're doing recursion to simply decrement the terms argument. This is not a good use of recursion (outside of a functional programming language optimized for tail recursion) and would be better implemented using a for loop. The good recursive paradigm for this would be to actually shorten the string:
public static void trianglePrint(String string) {
trianglePrint(string, 0);
}
public static void trianglePrint(String string, int padding) {
for (int i = 0; i < padding; i++) {
System.out.print(" ");
}
System.out.println(string);
if (string.length > 2) {
int midpoint = string.length()/2; //assumes string length is even
trianglePrint(string.substring(0, midpoint - 1) + string.substring(midpoint + 1), padding + 1);
}
}
Not necessarily the fastest code, but very simple.
A slightly different approach can simplify further by leveraging the recursion more fully for the padding. StringBuilder also makes it easier to delete from the middle of a string:
public static void trianglePrint2(String s) {
System.out.println(s);
int mid = s.length()/2;
if (!s.replace(" ", "").equals("")) //if not all spaces
trianglePrint(" " + new StringBuilder(s).delete(mid-1, mid+1) + " ");
}
or alternatively (more efficient):
public static void trianglePrint(String s) {
trianglePrint(s, s.length()/2);
}
public static void trianglePrint(String string, int mid) {
System.out.println(s);
if (string.length() > mid)
trianglePrint(" " + new StringBuilder(s).delete(mid-1, mid+1), mid);
}
Both will work with odd or even lengths.

Write a program to accept number from command line and display sum of digits in a number by using recursive funcion

I have written the code but it displays Stackoverflowerror message.
class Sum
{
int ans=0,temp,temp2;
int getsum(int no)
{
if(no>0)
{
temp=no % 10;
ans=ans + temp;
getsum(no/10);
}
else
{
return ans;
}
}
}
class recsum
{
public static void main(String args[])
{
Sum s=new Sum();
int no,len;
len=args.length;
if(len==0)
{
System.out.println("No argruments are given ! ");
}
else
{
no=Integer.valueOf(args[0]).intValue();
System.out.println("Sum of digits= " + s.getsum(no));
}
}
}
You are over-complicating things a lot in your code. Here is a simpler working example:
public static int getSum(final String[] args, final int index) {
if (index < args.length) {
return Integer.valueOf(args[index]) + getSum(args, index + 1);
} else {
return 0;
}
}
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("You need to provide numbers as arguments.");
}
final int sum = getSum(args, 0);
System.out.println("Sum: " + sum);
}
You are supposed to be recursive, this is in the getSum function, because it is calling itself with differing parameters.
In recursive functions, you always need to have an exit branch that causes the calling to stop.
As sums won't change if you add 0 this can be exploited for a very clean exit.
The Stack overflow is normally because you never bottom out of the recursion.
Change class Sum to this:
class Sum {
int ans = 0, temp = 0;
int getsum(int no) {
if((no/10)-.5 >= 1)
ans += getsum(no/10);
else
return ans;
}
}
I'm not completely sure if this will work, and I can't compile it right now. I think this is one way to do it, but again, I'm not completely sure.
Program: Write a program to use Command Line Arguments.
class Sumnum1
{
int i,t,num,sum=0;
void getData(String s)
{
num=Integer.parseInt(s);
}
int digitSum()
{
for(i=num;i>=1;i=i/10)
{
t=i%10;
sum=sum+t;
}
return sum;
}
public static void main(String arg[])
{
int ds=0;
Sumnum1 obj=new Sumnum1();
obj.getData(arg[0]);
ds=obj.digitSum();
System.out.println("sum of digit="+ds);
}
}
BY :ANKIT AGRAWAL (A.A.)

Uva's 3n+1 problem

I'm solving Uva's 3n+1 problem and I don't get why the judge is rejecting my answer. The time limit hasn't been exceeded and the all test cases I've tried have run correctly so far.
import java.io.*;
public class NewClass{
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
int maxCounter= 0;
int input;
int lowerBound;
int upperBound;
int counter;
int numberOfCycles;
int maxCycles= 0;
int lowerInt;
BufferedReader consoleInput = new BufferedReader(new InputStreamReader(System.in));
String line = consoleInput.readLine();
String [] splitted = line.split(" ");
lowerBound = Integer.parseInt(splitted[0]);
upperBound = Integer.parseInt(splitted[1]);
int [] recentlyused = new int[1000001];
if (lowerBound > upperBound )
{
int h = upperBound;
upperBound = lowerBound;
lowerBound = h;
}
lowerInt = lowerBound;
while (lowerBound <= upperBound)
{
counter = lowerBound;
numberOfCycles = 0;
if (recentlyused[counter] == 0)
{
while ( counter != 1 )
{
if (recentlyused[counter] != 0)
{
numberOfCycles = recentlyused[counter] + numberOfCycles;
counter = 1;
}
else
{
if (counter % 2 == 0)
{
counter = counter /2;
}
else
{
counter = 3*counter + 1;
}
numberOfCycles++;
}
}
}
else
{
numberOfCycles = recentlyused[counter] + numberOfCycles;
counter = 1;
}
recentlyused[lowerBound] = numberOfCycles;
if (numberOfCycles > maxCycles)
{
maxCycles = numberOfCycles;
}
lowerBound++;
}
System.out.println(lowerInt +" "+ upperBound+ " "+ (maxCycles+1));
}
}
Are you making sure to accept the entire input? It looks like your program terminates after reading only one line, and then processing one line. You need to be able to accept the entire sample input at once.
I faced the same problem. The following changes worked for me:
Changed the class name to Main.
Removed the public modifier from the class name.
The following code gave a compilation error:
public class Optimal_Parking_11364 {
public static void main(String[] args) {
...
}
}
Whereas after the changes, the following code was accepted:
class Main {
public static void main(String[] args) {
...
}
}
This was a very very simple program. Hopefully, the same trick will also work for more complex programs.
If I understand correctly you are using a memoizing approach. You create a table where you store full results for all the elements you have already calculated so that you do not need to re-calculate results that you already know (calculated before).
The approach itself is not wrong, but there are a couple of things you must take into account. First, the input consists of a list of pairs, you are only processing the first pair. Then, you must take care of your memoizing table limits. You are assuming that all numbers you will hit fall in the range [1...1000001), but that is not true. For the input number 999999 (first odd number below the upper limit) the first operation will turn it into 3*n+1, which is way beyond the upper limit of the memoization table.
Some other things you may want to consider are halving the memoization table and only memorize odd numbers, since you can implement the divide by two operation almost free with bit operations (and checking for even-ness is also just one bit operation).
Did you make sure that the output was in the same order specified in the input. I see where you are swapping the input if the first input was higher than the second, but you also need to make sure that you don't alter the order it appears in the input when you print the results out.
ex.
Input
10 1
Output
10 1 20
If possible Please use this Java specification : to read input lines
http://online-judge.uva.es/problemset/data/p100.java.html
I think the most important thing in UVA judge is 1) Get the output Exactly same , No Extra Lines at the end or anywhere . 2) I am assuming , Never throw exception just return or break with No output for Outside boundary parameters.
3)Output is case sensitive 4)Output Parameters should Maintain Space as shown in problem
One possible solution based on above patterns is here
https://gist.github.com/4676999
/*
Problem URL: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=36
Home>Online Judge > submission Specifications
Sample code to read input is from : http://online-judge.uva.es/problemset/data/p100.java.html
Runtime : 1.068
*/
import java.io.*;
import java.util.*;
class Main
{
static String ReadLn (int maxLg) // utility function to read from stdin
{
byte lin[] = new byte [maxLg];
int lg = 0, car = -1;
String line = "";
try
{
while (lg < maxLg)
{
car = System.in.read();
if ((car < 0) || (car == '\n')) break;
lin [lg++] += car;
}
}
catch (IOException e)
{
return (null);
}
if ((car < 0) && (lg == 0)) return (null); // eof
return (new String (lin, 0, lg));
}
public static void main (String args[]) // entry point from OS
{
Main myWork = new Main(); // create a dinamic instance
myWork.Begin(); // the true entry point
}
void Begin()
{
String input;
StringTokenizer idata;
int a, b,max;
while ((input = Main.ReadLn (255)) != null)
{
idata = new StringTokenizer (input);
a = Integer.parseInt (idata.nextToken());
b = Integer.parseInt (idata.nextToken());
if (a<b){
max=work(a,b);
}else{
max=work(b,a);
}
System.out.println (a + " " + b + " " +max);
}
}
int work( int a , int b){
int max=0;
for ( int i=a;i<=b;i++){
int temp=process(i);
if (temp>max) max=temp;
}
return max;
}
int process (long n){
int count=1;
while(n!=1){
count++;
if (n%2==1){
n=n*3+1;
}else{
n=n>>1;
}
}
return count;
}
}
Please consider that the integers i and j must appear in the output in the same order in which they appeared in the input, so for:
10 1
You should print
10 1 20
package pandarium.java.preparing2topcoder;/*
* Main.java
* java program model for www.programming-challenges.com
*/
import java.io.*;
import java.util.*;
class Main implements Runnable{
static String ReadLn(int maxLg){ // utility function to read from stdin,
// Provided by Programming-challenges, edit for style only
byte lin[] = new byte [maxLg];
int lg = 0, car = -1;
String line = "";
try
{
while (lg < maxLg)
{
car = System.in.read();
if ((car < 0) || (car == '\n')) break;
lin [lg++] += car;
}
}
catch (IOException e)
{
return (null);
}
if ((car < 0) && (lg == 0)) return (null); // eof
return (new String (lin, 0, lg));
}
public static void main(String args[]) // entry point from OS
{
Main myWork = new Main(); // Construct the bootloader
myWork.run(); // execute
}
public void run() {
new myStuff().run();
}
}
class myStuff implements Runnable{
private String input;
private StringTokenizer idata;
private List<Integer> maxes;
public void run(){
String input;
StringTokenizer idata;
int a, b,max=Integer.MIN_VALUE;
while ((input = Main.ReadLn (255)) != null)
{
max=Integer.MIN_VALUE;
maxes=new ArrayList<Integer>();
idata = new StringTokenizer (input);
a = Integer.parseInt (idata.nextToken());
b = Integer.parseInt (idata.nextToken());
System.out.println(a + " " + b + " "+max);
}
}
private static int getCyclesCount(long counter){
int cyclesCount=0;
while (counter!=1)
{
if(counter%2==0)
counter=counter>>1;
else
counter=counter*3+1;
cyclesCount++;
}
cyclesCount++;
return cyclesCount;
}
// You can insert more classes here if you want.
}
This solution gets accepted within 0.5s. I had to remove the package modifier.
import java.util.*;
public class Main {
static Map<Integer, Integer> map = new HashMap<>();
private static int f(int N) {
if (N == 1) {
return 1;
}
if (map.containsKey(N)) {
return map.get(N);
}
if (N % 2 == 0) {
N >>= 1;
map.put(N, f(N));
return 1 + map.get(N);
} else {
N = 3*N + 1;
map.put(N, f(N) );
return 1 + map.get(N);
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
while(scanner.hasNextLine()) {
int i = scanner.nextInt();
int j = scanner.nextInt();
int maxx = 0;
if (i <= j) {
for(int m = i; m <= j; m++) {
maxx = Math.max(Main.f(m), maxx);
}
} else {
for(int m = j; m <= i; m++) {
maxx = Math.max(Main.f(m), maxx);
}
}
System.out.println(i + " " + j + " " + maxx);
}
System.exit(0);
} catch (Exception e) {
}
}
}

Categories

Resources