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

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

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

swapping of numbers using index in java is not working

package dspermutation;
import java.util.Scanner;
public class DSPermutation {
String s;
char[] c;
int n;
public static void main(String[] args) {
DSPermutation ds=new DSPermutation();
ds.input();
}
private void input() {
Scanner sc=new Scanner(System.in);
System.out.println("Enter the string");
s=sc.next();
c=s.toCharArray();
n=c.length;
permutation(c,n-1,0);
}
private void permutation(char[] cc,int nn,int ii) {
if(ii==nn)
{
System.out.println(cc);
}
else
{
for(int j=ii;j<=nn;j++)
{
swap(cc[ii],cc[j]);
permutation(cc,nn,ii+1);
swap(cc[ii],cc[j]);
}
}
}
private void swap(char p, char c0) {
int x=s.indexOf(p);
int y=s.indexOf(c0);
/*1*/ char temp=c[x];
/*2*/c[x]=c[y];
/*3*/c[y]=temp;
/*c[x]=c0;
c[y]=p;*/
}
}
The above program is for printing all permutations of a given string.The result is coming true but in swap() method if i replace line 1,2,3(written in comment) by logic written in comment(after line 1,2,3) then answer comes wrong. Why could this be happening?
Your mistake is assuming c[x] == p and c[y] == c0. But the indexes x and y are derived from the immutable string s, which doesn't reflect the values in c in its shuffled state.
You are swapping values of character array using immutable string's position (i.e String always holds the same initial values). To make your commented code work you have to add this s = String.valueOf(c);at the end of swap function.
private void swap(char p, char c0) {
int x = s.indexOf(p);
int y = s.indexOf(c0);
// char temp = c[x];
// c[x] = c[y];
// c[y] = temp;
c[y] = p;
c[x] = c0;
s = String.valueOf(c);
}

Implementation of Radix sort in Java using Nodes instead of integers

I have a final project for my Data Structures class that I can't figure out how to do. I need to implement Radix sort and I understand the concept for the most part. But all the implementations I found online so far are using it strictly with integers and I need to use it with the other Type that I have created called Note which is a string with ID parameter.
Here is what I have so far but unfortunately it does not pass any JUnit test.
package edu.drew.note;
public class RadixSort implements SortInterface {
public static void Radix(Note[] note){
// Largest place for a 32-bit int is the 1 billion's place
for(int place=1; place <= 1000000000; place *= 10){
// Use counting sort at each digit's place
note = countingSort(note, place);
}
//return note;
}
private static Note[] countingSort(Note[] note, long place){ //Where the sorting actually happens
Note[] output = new Note[note.length]; //Creating a new note that would be our output.
int[] count = new int[10]; //Creating a counter
for(int i=0; i < note.length; i++){ //For loop that calculates
int digit = getDigit(note[i].getID(), place);
count[digit] += 1;
}
for(int i=1; i < count.length; i++){
count[i] += count[i-1];
}
for(int i = note.length-1; i >= 0; i--){
int digit = getDigit((note[i].getID()), place);
output[count[digit]-1] = note[i];
count[digit]--;
}
return output;
}
private static int getDigit(long value, long digitPlace){ //Takes value of Note[i] and i. Returns digit.
return (int) ((value/digitPlace ) % 10);
}
public Note[] sort(Note[] s) { //
Radix(s);
return s;
}
//Main Method
public static void main(String[] args) {
// make an array of notes
Note q = new Note(" ", " ");
Note n = new Note("CSCI 230 Project Plan",
"Each person will number their top 5 choices.\n" +
"By next week, Dr. Hill will assign which piece\n" +
"everyone will work on.\n");
n.tag("CSCI 230");
n.tag("final project");
Note[] Note = {q,n};
//print out not id's
System.out.println(Note + " Worked");
//call radix
Radix(Note);
System.out.println(Note);
//print out note_id's
}
}
Instead of
public Note[] sort(Note[] s) { //
Radix(s);
return s;
}
I should have used
public Note[] sort(Note[] s) { //
s = Radix(s);
return s;
}
and change the variable type of Radix from void to Note[].

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.

Java Fitness Function - Scales

I have a fitness function as part of a lab and wish to apply it to a set of 'weights' (ArrayList weights). I have created the array and stored some values in it. I have created random binary strings (which have an 'x' at the end in order to generate random values) which I wish to also apply the fitness function to; however, the problem I am having is that the fitness function always returns a value of 0. Am I missing something here?
The fitness function is as follows:
import java.util.*;
public class ScalesSolution{
private static String scasol;
//Creates a new scales solution based on a string parameter
//The string parameter is checked to see if it contains all zeros and ones
//Otherwise the random binary string generator is used (n = length of parameter)
public ScalesSolution(String s)
{
boolean ok = true;
int n = s.length();
for(int i=0;i<n;++i)
{
char si = s.charAt(i);
if (si != '0' && si != '1') ok = false;
}
if (ok)
{
scasol = s;
}
else
{
scasol = RandomBinaryString(n);
}
}
private static String RandomBinaryString(int n)
{
String s = new String();
//Code goes here
//Create a random binary string of just ones and zeros of length n
for(int i = 0; i < n; i++){
int x = CS2004.UI(0,1);
if(x == 0){
System.out.print(s + '0');
}
else if(x == 1){
System.out.print(s + '1');
}
}
return(s);
}
public ScalesSolution(int n)
{
scasol = RandomBinaryString(n);
}
//This is the fitness function for the Scales problem
//This function returns -1 if the number of weights is less than
//the size of the current solution
//EXERCISE 3
public static double ScalesFitness(ArrayList<Double> weights)
{
int n = scasol.length();
double lhs = 0.0, rhs = 0.0;
if (n > weights.size()) return(-1);
for(int i = 0; i < n; i++){
if(scasol.charAt(i) == 0){
lhs += weights.get(i);
}
else{
rhs += weights.get(i);
}
}
//Code goes here
//Check each element of scasol for a 0 (lhs) and 1 (rhs) add the weight wi
//to variables lhs and rhs as appropriate
return(Math.abs(lhs-rhs));
}
//Display the string without a new line
public void print()
{
System.out.print(scasol);
}
//Display the string with a new line
public void println()
{
print();
System.out.println();
}}
Main method (in separate class):
import java.util.ArrayList;
public class Lab8 {
public static void main(String args[])
{
for(int i = 0; i < 10; i++){
ScalesSolution s = new ScalesSolution("10101x");
s.println();
}
ArrayList<Double> weights = new ArrayList<Double>();
weights.add(1.0);
weights.add(2.0);
weights.add(3.0);
weights.add(4.0);
weights.add(10.0);
System.out.println();
System.out.println(weights);
System.out.print("Fitness: ");
double fitness = ScalesSolution.ScalesFitness(weights);
System.out.println(fitness);
}}
CS2004 class:
import java.util.*;
import java.io.*;
//Some useful code that we will probably reuse in later laboratories...
public class CS2004
{
//Shared random object
static private Random rand;
//Create a uniformly distributed random integer between aa and bb inclusive
static public int UI(int aa,int bb)
{
int a = Math.min(aa,bb);
int b = Math.max(aa,bb);
if (rand == null)
{
rand = new Random();
rand.setSeed(System.nanoTime());
}
int d = b - a + 1;
int x = rand.nextInt(d) + a;
return(x);
}
//Create a uniformly distributed random double between a and b inclusive
static public double UR(double a,double b)
{
if (rand == null)
{
rand = new Random();
rand.setSeed(System.nanoTime());
}
return((b-a)*rand.nextDouble()+a);
}
//This method reads in a text file and parses all of the numbers in it
//This code is not very good and can be improved!
//But it should work!!!
//It takes in as input a string filename and returns an array list of Doubles
static public ArrayList<Double> ReadNumberFile(String filename)
{
ArrayList<Double> res = new ArrayList<Double>();
Reader r;
try
{
r = new BufferedReader(new FileReader(filename));
StreamTokenizer stok = new StreamTokenizer(r);
stok.parseNumbers();
stok.nextToken();
while (stok.ttype != StreamTokenizer.TT_EOF)
{
if (stok.ttype == StreamTokenizer.TT_NUMBER)
{
res.add(stok.nval);
}
stok.nextToken();
}
}
catch(Exception E)
{
System.out.println("+++ReadFile: "+E.getMessage());
}
return(res);
}}
Once run, the random binary strings work perfectly well, yet the fitness function fails to change from 0. Here is a sample output:
011100
111010
001110
111011
001000
010101
001010
100011
110100
011001
[1.0, 2.0, 3.0, 4.0, 10.0]
Fitness: 0.0
Thank you all so much for your time.
Stefanos.
scasol appears to be empty when ScalesFitness is called. In the RandomBinaryString method, you never actually construct s, but rather, just print it out. Instead of System.out.print(s+'0') and the other line, you should have s += '0';.
Since this appears to be an exercise, I'll leave the rest to you, but here is a tip for next time: don't have a function do more than it's supposed to (such as printing out its results), otherwise, it might look like the set of functions is actually working, when in reality it isn't.
In this case, it looked like everything was working fine since it appeared like the s.println() function what actually printing out scasol, but in reality, scasol was empty and the RandomBinaryString method was actually doing the printing.

Categories

Resources