I need to write a printBackwards() method, using three pre-given methods first, rest and length. printBackwards() method needs to take String as a parameter and prints each letter of that string on the console, but each letter needs to be printed on new line and in reverse order. So if the String is House, the output should be:
e
s
u
o
H
In this exercise, we should use recursion and if-else statements. No arrays, no other (familiar) String method, no while and for loop.
I have done a little bit, I know it is not correct, but that is how much I managed to do. I dont understand how to write code so the method can return letters before letter e. How to use recursion here ?
public class Recurse {
public static void main(String args[]){
System.out.println(printBackwards("House"));
}
//printBackward: takes a String as a parameter and prints letters of the String,
// one on each line, but backwards
public static String printBackwards(String s){
if (length(s) == 1){
return s;
} else {
return printBackwards(rest(s));
}
}
// first: returns the first character of the given String
public static char first(String s) {
return s.charAt(0);
}
// last: returns a new String that contains all but the
// first letter of the given String
public static String rest(String s) {
return s.substring(1, s.length());
}
// length: returns the length of the given String
public static int length(String s) {
return s.length();
}
}
Because this is a homework question, I'll leave as much as possible to you, so you learn.
Consider these two facts:
You must print the first character after you have printed the rest
If the string is empty, print nothing
Use these two facts are enough to build a recursive method.
Point 2. is the terminating condition. It's best to code this first.
Point 1. is the main method body, where printing the rest is done using recursion
Once you have your terminating condition and your recursive structure (often, a pre-order or a post-order operation), you can build a recursive method.
Note also the name of the method printBackwards() (not backwards()). That is, the method does the printing; it doesn't return the String backwards.
So, translating the above into pseudo-code (which in this case is practically the code):
if the string is empty do nothing
call self with the rest of the string
print the first character
First of all you need to print the output within the printBackwards function, so the main will look like this:
public static void main(String args[])
{
printBackwards("House");
}
Second, is the way recursion works. If you want it to be executed in the ascending order, you should do stuff before the self function call. Otherwise, in case of descending execution order, you code should be executed after the self calling function. These are the basic principles of the recursion function.
In this case, let's try to build the answer.
First, we need to handle the stop condition, which should be always written before the self calling function. The best and most common stop condition, is to reach to the end of something, in this case it is when we get an empty string, in all other cases we need to call the self function with a slight of a change, in this case it will be providing the rest of the string to the function:
if ( !length(s) )
{
//stop the recursion
return;
}
else
{
printBackwards(rest(s));
}
When you reach the stop recursion statement, from this point and on, it will close all the opened self function executions, therefor will go backward.
This is the perfect state of what we need to achieve, print the letters backward and because on each state of the printBackwards execution, we have sliced the string a bit from the left letters, it means that the first letter is the one we need.
For example, in case of the string House the last call of the printBackwards function will be when the s variable will hold the e value, because it is one stem from being cut-off to an empty string, when we reach the stop condition. In this case we want to print it out, but in the self call before this one, the s variable will hold the value se, because it is one step before cutting the first letter. So, we not want to print the whole value, but only the first letter of it, like this:
System.out.println(first(s));
Combining everything together, will result the following implementation:
public static String printBackwards(String s)
{
if ( !length(s) )
{
//stop the recursion
return;
}
else
{
printBackwards(rest(s));
System.out.println(first(s));
}
}
Hope, I explained it clearly.
Good luck!
Related
Please pardon my understanding towards priority Queue and Comparator in Java.
It seems ,I am able to implement basic comparator for Priority Queue based on some sort order.
But I am not able to come up with something for the below scenario :
1. Given a list of Files with name convention xx_yy_zz.dat .<br/>
2.xx,yy,zz can be from 00-50 <br/>
3.I need to process the files with xx=30 first,xx=35 second xx=40 third and then the rest.<br/>
Since I have limited knowledge with Priority Queue ,I tried to implement it which i was able to sort but only in asc or desc value of xx which was not the requirement.
My approach was
put the list of file names in priority Queue ,split the filename on regex "_"
then compare the first index of split array using comparator based on it values but as expected i failed miserably since my requirement was something different
Please share some ideas/approach.
It seems sadly ,I am not able to come up with the a required comparator for my case .
Nevertheless thanking you in anticipation
You can use simple if statements inside the compare() method to check if one string starts with "30" and the other does not. Then you know that this string must come before the other one. You run the following if statements like this on the first part of the filenames:
Are they the same?
Is the left one 30?
Is the right one 30?
Is the left one 35?
Is the right one 35?
Is the left one 40?
Is the right one 40?
The comparator might look like this:
public int compare(String a, String b) {
String[] splitA = a.split("_");
String[] splitB = b.split("_");
if (splitA[0].equals(splitB[0])) {
return 0;
}
if (splitA[0].equals("30")) {
return -1;
}
if (splitB[0].equals("30")) {
return 1;
}
if (splitA[0].equals("35")) {
return -1;
}
if (splitB[0].equals("35")) {
return 1;
}
if (splitA[0].equals("40")) {
return -1;
}
if (splitB[0].equals("40")) {
return 1;
}
return 0;
}
With the following test source code:
System.out.println(Arrays.toString(data));
Arrays.sort(data, new SpecialComparator());
System.out.println(Arrays.toString(data));
You might get an output like this (depending on the data array):
[30_45_35.dat, 00_12_34.dat, 35_50_20.dat, 40_03_05.dat, 33_28_14.dat,
30_16_31.dat, 20_29_23.dat, 24_41_29.dat, 30_49_18.dat, 40_12_13.dat]
[30_45_35.dat, 30_16_31.dat, 30_49_18.dat, 35_50_20.dat, 40_03_05.dat,
40_12_13.dat, 00_12_34.dat, 33_28_14.dat, 20_29_23.dat, 24_41_29.dat]
(new lines added for clarity)
As you see you have the 30s first, then the only 35 second, then the 40s third and after that all the remaining stuff. You might want to use compareTo() on the strings in case the compareTo method would return 0 to get better "sub sorting" of strings, which would be equal based on this basic sorting above.
May be I'm not understand what exactly you need... but simply try this code and it sort me all strings if they has two digits on the begining
public static void main(String[] args) {
PriorityQueue<String> q = new PriorityQueue<String>((first, second) -> {
return Integer.parseInt(first.substring(0, 2)) - Integer.parseInt(second.substring(0, 2));
//and if you want to reverse order, simply add "-" like this:
//return -(Integer.parseInt(first.substring(0, 2)) - Integer.parseInt(second.substring(0, 2)));
});
q.add("23lk");
q.add("22lkjl");
q.add("45ljl");
for(String str : q) {
System.out.println(str);
}
}
}
adn output
22lkjl
23lk
45ljl
If this not solution, please explain problem with more details, may be I or anybody else will help you.
I am not able to understand how this will work as printAll is called from itself and calling in a for loop so how this function will reach at end. as when we call printAll from the for loop it will go and start the method again without ending it and then again comes to for loop and call printAll method without ending it and it will continuos do this, so can anyone explain how this funtions will work. because I am not able to understand this phenomenon.
private void printAll(Integer u, Integer d, List<Integer> savearray) {
if (u.equals(d)) {
this.saveinlist = new ArrayList<Integer>(savearray);
return ;
}
for (Integer i : adjList[u]) {
savearray.add(i);
printAll(i, d, savearray);
savearray.remove(i);
}
}
This is a Recursive method. In a recursive method there are two parts.
1. Base condition
2. Recursive part
Base condition is which when we want to stop this recursive calling.
In recursive part it called it self with some arguments. Because we have to use same set of codes to get our result.
https://www.geeksforgeeks.org/recursion/ go to this link if you know more about
Let's assume that we have a for-loop that will loop through a collection or array of Strings. In that case, I am searching for a specific keyword (ex. hey) here's how I usually achieve that:
for (String result : strings)
{
if (result == "hey")
{
// Do something with that.
break;
}
}
Now, the question arises from that code snippet is, should I place a keyword (return or break) when the if-statement returns true so the loop will not continue? If not, what will happen and what's the correct way of going about it.
Edit: What happens when you use break and return? What's the difference?
Let's put your code inside a method:
private void foo()
{
for (String result : strings)
{
if (result.equals("hey"))
{
// Do something with that.
break;
}
}
bar();
}
If you use break;, the loop will terminate and bar will be reached. If you use return, the method will terminate and bar won't be executed.
Note that comparing strings should be done using equals, == compares references and not content.
If you know the word can only be found once you can surely place an break; statement so the loop won't continue after finding the match.
If you can have more than one match and you want the if block to be executed for each of those matches you should NOT put the break statement since it will stop the execution of the loop after the first match is found.
I have written a method with the aim to count the number of times a specific flavour of crisps appears in a snack machine in blueJ
public int countPacks(String flavour){
int n = 0;
int nrFlavour = 0;
while( n < packets.size()) {
if( packets.get(n).equals(flavour)){
nrFlavour++;
n++;
}
else n++;
}
return nrFlavour;
}
I have an Arraylist 'packets' which holds PackOfCrisps objects which have a specific flavour. However when I have added say three packets of "salt" flavour crisps and I run this method, inputting "salt" as the flavour, it just returns 0 as though there are no PackOfCrisps objects with flavour "salt".
Sorry if this doesn't make sense. I am very new to Java and I have tried to explain my problem the best I can. :)
The list packets holds PackOfCrisps objects, and the method takes a String parameter. So the statement packets.get(n).equals(flavour) is comparing a PackOfCrisps object to a String, hence the count variable will never increase.
You need to compare the flavour string to the specific field of the object, something like:
if(packets.get(n).getFlavour().equals(flavour)){
On a side note, you can replace the while loop with a simple for loop and remove the increment of n.
There is a built-in solution to your problem, you can use this method
You can rewrite your countPacks method like this :
public int countPacks(String flavour){
return Collections.frequency(packets, flavour);
}
I've done most part of this. Anyone give me a small hint about how do I find the number of 10s in the list.
Eg. Input would be
[10,4,6,10,6,7]
Output must be
[4,6,6,7,0,0]
import java.util.ArrayList;
import java.util.List;
public class prob64 {
public static List output;
public static void getVal(List ll)
{
int count=0;
List ll1=new ArrayList();
for(int i=0;i<ll.size();i++)
{
if((int)ll.get(i)!=10)
{
ll1.add(ll.get(i));
}
if((int)ll.get(i)==10)
{
count++;
}
}
if(count>0)
{
ll1.add(8);
}
output=ll1;
System.out.println(output);
}
public static void main(String[] args) {
List<Integer> ll=new ArrayList();
ll.add(10);
ll.add(1);
ll.add(10);
ll.add(2);
prob64.getVal(ll);
}
}
The current output I'm getting is [1,2,0]. I'm supposed to get [1,2,0,0]
List.remove(Object) removes the first matching element. It also returns a boolean indicating if a removal was really done, so this should work :
while(ll.remove(10)) {
ll.add(0);
}
That is, as long as you find 10s to remove, add 0s. Note that List.add adds the element at the end of the list, which is your requirement (if I'm correct).
I suppose this is some kind of learning exercise, but I would advise you to find better names for your variable (ll & ll1 does not make your function easy to read).
You are adding only one zero at the end of the loop (in case 10s were found). You should count the number of 10s then add zeros as much as this number. Your program should look something like this:
int count=0;
List ll1=new ArrayList();
for(int i=0;i<ll.size();i++)
{
if((int)ll.get(i)!=10)
ll1.add(ll.get(i));
else
count++;
}
for(int j=0; j<count;j++)
ll1.add(0);
If count is number of 10's to add, use:
for(int j=0; j<count;j++){
ll1.add(8); // or ll1.add(0); ???
}
Few points to add to what others have mentioned above
I don't see any reason why you must define the output List to be static. When you define something(variables/functions) as static they are owned by the class rather that the objects and also it is a good programming practice not to change them using instance functions.What I mean is if you wish only to print there is no need of that output instance variable. You can directly print ll1.
Please use Generics in your code. When you know all you have in your list are integers specify it - Even in the function getVal(). I don't know how your code is compiling but you cannot cast Object to an int.
(int)ll.get(i)!=10
This code will fail. Try using Integer instead of int.
Your problem statement read replacing all 10's with 0's. So why are you adding 8 instead.It must be
ll1.add(0);
As other have specifies you need to add 0 as many time as your count is. So another loop is needed. Rest all look good.