java : Inverted string triangle using recursion? - java

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.

Related

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");

Need help converting iterative process to recursive

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);
}

Java Exercise: Printing asterisks Triangle and its inverted triangle using recursion method

I need to print a triangle and its inverted triangle (standing on its tip). I manage to print out only the triangle. I know I can easily use for loop but I want to know how to make use recursion and in my case, I don't know how to print the both triangle and the inverted one.Thank you.
Example desired output:
*
**
***
****
****
***
**
*
My code:
public class Recursion1 {
public static void main(String[] args) {
Recursion1 me = new Recursion1();
me.doIt();
}
public void doIt() {
nums(4);
}
public String nums(int counts) {
if (counts <= 0) {
return "";
}
String p = nums(counts - 1);
p = p +"*";
System.out.print(p);
System.out.println();
return p;
}
}
My result:
Results:
*
**
***
****
You have to rethink the problem, this could be a possible solution:
public class Recursion1 {
private static int endValue;
private static int startValue = 1 ;
public Recursion1(int endValue){
Recursion1.endValue = endValue;
}
public static void main(String[] args) {
Recursion1 me = new Recursion1(4);
me.doIt();
}
public void doIt() {
nums("*");
}
public String nums(String value) {
if( startValue == endValue){
System.out.println(value);
}else{
System.out.println(value);
startValue ++;
value = value.concat("*");
nums(value);
value = value.substring(1);
System.out.println(value);
}
return value;
}}
I would recommend to keep the creation of the resulting String separate from printing. That would allow you to do anything else you want with the result and it's likely to be more efficient. Also for efficiency, StringBuilder is recommended as it avoids creating and discarding many String objects. Also for efficiency prefer appending a single char instead of a String with a single char.
Here is a solution with these in mind. You pass as argument an initial count of zero, the number of lines and a new StringBuilder. The number of * appended increases up to half the number of lines and then decreases. New line is appended in each recursive call.
public void doIt() {
String p = nums(0, 7, new StringBuilder());
System.out.print(p);
}
public String nums(int counts, int lines, StringBuilder b) {
if (counts == lines)
return b.toString();
int size = counts < lines / 2 ?
counts :
lines - counts - 1;
for (int i = 0; i < size + 1; ++i)
b.append('*');
b.append('\n');
return nums(counts + 1, lines, b);
}

A RECURSIVE method accepts two parameters: a String s and an int n

(I actually don't know how to write this code, I checked internet find it maybe look like this, but when I run it, it didnt work.
For example, input ("College",2). It should output ("College","College"). But it shows cannot read.
I just don't know how to solve this problem.
Please teach me how to write this code.
-------Write a RECURSIVE method called printStr that accepts two parameters: a String s and an int n. This method should return a String containing the String s written n times, separated by a space each time. Assume n >= 1.
For example, calling printStr("Lehman", 2) should return "Lehman Lehman", and calling printStr("The Bronx", 4) should return "The Bronx The Bronx The Bronx The Bronx".
Call your class Homework5_2. In the main method, call your method printStr several times to test it.
import java.util.Scanner;
public class Homework5_2 {
public static void main(String[] args) {
Scanner keyboard=new Scanner(System.in);
int n = 0;
String s = args[1];
System.out.print(printStr(s,n));
}
public static String printStr(String s, int n){
if (n==0) {
return "";
}
return s + printStr(s, n - 1);
}
Couple of issues with your code. Quoting assignment as you posted it:
"separated by a space"
"Assume n >= 1"
"In the main method, call your method printStr several times to test it."
So, write explicit calls in main(), don't use args. Add the missing space, and don't call or check for 0:
public static void main(String[] args) {
System.out.println('"' + printStr("College", 2) + '"');
System.out.println('"' + printStr("Lehman", 2) + '"');
System.out.println('"' + printStr("The Bronx", 4) + '"');
}
public static String printStr(String s, int n) {
if (n == 1)
return s;
return s + ' ' + printStr(s, n - 1);
}
Added quote ('"') to println() to ensure no extra spaces were added.
Output
"College College"
"Lehman Lehman"
"The Bronx The Bronx The Bronx The Bronx"
Alright, take your homework. But it will be better if you will try harder to do something by yourself.
static int maxn;
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
String s = scanner.next();
maxn = scanner.nextInt();
System.out.print(printStr(s, 0));
}
public static String printStr(String s, int n){
if(n == maxn){
return "";
} else if (n != 0){
s = " " + s;
}
return s + printStr(s, n + 1);
}
Not sure whats wrong with your code... just didnt put a space..
public static String printStr(String s, int n) {
if (n == 1) {
return s;
}
return s + " " + printStr(s, n - 1);
}
Add space and give newline at the last of string.
public static String printStr(String s, int n){
if (n==0) {
return "\n";
}
return s+" " + printStr(s, n - 1);
}

This Java program converts a natural number into a set-theoretic encoding using iteration. Request help/strategies for a recursive solution?

I'm trying to get a better understanding of ZFC set theory, in particular how a computer program might model the axiom of infinity to "construct" natural numbers. The typical symbols I've seen used to construct the natural numbers are: "{", "}", and ",". The code below works, but I'm hoping for a purely recursive solution. One that given a natural number (here using int), recursively builds up the corresponding string into its set-theoretic encoding and then returns it. Ideally, I hope for it to work without using any extra data structures like the String array currently being used.It's ok if the runtime is slow (exponential). Using recursion sometimes makes the expression of the process simpler, more condensed/elegant and easier to understand, and I would very much like to see what such a solution for this might look like, regardless of performance. Ultimately, I'd like a better understanding of foundations of math/numbers. I have many questions but thought this might be a good way to begin. Thanks!
// Converts an natural number to its ZFC set notation:
// 0 = {}, 1 = {0} = {{}}, 2 = {0,1} = {{},{{}}},
// 3 = {0,1,2} = {{},{{}},{{},{{}}}} ...
import java.util.Scanner;
public class IntToSetNotation {
private static final String openBrace = "{";
private static final String closeBrace = "}";
private static final String seperator = ",";
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
System.out.println(getSetNotationFromInt(n));
}
private static String getSetNotationFromInt(int n) {
String[] nums = new String[n+1];
nums[0] = openBrace + closeBrace;
for (int i = 1; i < nums.length; i++) {
if(i == nums.length-1)
nums[i] = openBrace + getPrevSets(i,nums) + closeBrace;
else
nums[i] = seperator + openBrace + getPrevSets(i,nums) + closeBrace;
}
return nums[n];
}
private static String getPrevSets(int n, String[] nums) {
String s = "";
for (int i = 0; i<n; i++)
s += nums[i];
return s;
}
}
So recursion sounds really difficult, but it's actually kind of simple once you get over the name.
Recursion needs to things: a base case to stop recursing, and an output to do what you want.
Say you want to write a recursive problem that takes in a number x, and returns a specific pattern of curly braces:
0 == (nothing)
1 == {}
2 == {{}}
3 == {{{}}}
...
So, your recursive method is going to take one integer.
Now, lets look at the method output. If we call the recursive method on 1, we want to return {}. Easy. In terms of java, we'll be returning a string.
Great, now we know the return type of the method.
If we call recursive method on 2, we want the method to first output {}, and then we want the method to execute AGAIN, but this time, we are putting a curly AT THE BEGINNING, and one curly AT THE END.
This is the part that is hard to explain. Imagine recursion as a loop. Eventually, we want the recursion to terminate. Say we call the method initially on 3. We want {{{}}} to be returned. First, our method will return {}, followed by {{}}, then {{{}}}. It runs a total of 3 times.
In the recursive call, you have to call it one less than the initial call.
Ok, now you say, if we are subtracting 1 each time and calling the method again, how do we get it to stop?
That's called the base case. If the method is called on 0, we don't want to return anything, thus we want to exit out of the method with a simple return statement.
Apply this to your own problem, and you should be good.
String exampleRecursiveMethod(int x){
if(x==0)return "";
else return exampleRecursiveMethod(x-1)
}
This is an example to get you started. The return statement after the else is called the recursive call, I talked about it above.
I came up with the below code as a recursive solution. It works, but I wonder if there is anyway to streamline it, perhaps to use less methods? Any thoughts or comments are welcome.
public class IntToSetNotationRecursive {
private static final String openBrace = "{";
private static final String closeBrace = "}";
private static final String seperator = ",";
public static void main(String[] args) {
for (int i = 0; i < 6; i++) {
System.out.println(i + " = " + getSetNotationFromInt(i));
}
}
static String getSetNotationFromInt(int n){
return helper1(n, n, "");
}
static String helper1(int n, int x, String s){
if(x<=0)
return openBrace + s + closeBrace;
return helper1(n, x-1, helper2(x-1) + ((x != n ) ? seperator : "") + s);
}
static String helper2(int x){
if(x<=0)return openBrace+closeBrace;
else return helper1(x, x, "");
}
}
Prints:
0 = {}
1 = {{}}
2 = {{},{{}}}
3 = {{},{{}},{{},{{}}}}
4 = {{},{{}},{{},{{}}},{{},{{}},{{},{{}}}}}
5 = {{},{{}},{{},{{}}},{{},{{}},{{},{{}}}},{{},{{}},{{},{{}}},{{},{{}},{{},{{}}}}}}
The second helper method isn't necessary. Here is a shortened version.
public class IntToSetNotationRecursive {
private static final String openBrace = "{";
private static final String closeBrace = "}";
private static final String separator = ",";
public static void main(String[] args) {
for (int i = 0; i < 6; i++) {
System.out.println(i + " = " + getSetNotationFromInt(i));
}
}
static String getSetNotationFromInt(int n){
return helper1(n, n, "");
}
static String helper1(int n, int x, String s){
if(x<=0)
return openBrace + s + closeBrace;
return helper1(n, x-1, helper1(x-1,x-1,"") + ((x != n ) ? separator : "") + s);
}
}
Prints:
0 = {}
1 = {{}}
2 = {{},{{}}}
3 = {{},{{}},{{},{{}}}}
4 = {{},{{}},{{},{{}}},{{},{{}},{{},{{}}}}}
5 = {{},{{}},{{},{{}}},{{},{{}},{{},{{}}}},{{},{{}},{{},{{}}},{{},{{}},{{},{{}}}}}}

Categories

Resources