Reverse words from SCANNER using STACK and RECURSION - java

Is there a way to get words from SCANNER and reverse them with both STACK and RECURSION? I need all three aspects in this program. I am able to do this with Stack alone or with Recursion alone but I have not been able to make both work together.
public class Reverse {
public static String wordReverse(String[] theWords) {
Stack <String> stacker = new Stack <String>();
for(String wordsHold : theWords) {
stacker.push(wordsHold);
}
while ( !stacker.empty() ) {
stacker.pop();
}
return wordReverse(theWords); // Cause of StackOverflowError
}
public static void main(String args[]) {
Scanner takeIn = new Scanner(System.in);
String allWords = takeIn.nextLine();
String[] goodWords = allWords.split(" ");
System.out.println(wordReverse(goodWords));
takeIn.close();
}
}

The first thing to remember when recursing, is to define the stop condition;
public static String wordReverse(String[] theWords, Stack<String> stack) {
// stop on null.
if (theWords == null) {
return null;
} else if (theWords.length < 2) {
// stop if there are fewer then two words.
return theWords[0];
}
// push the first word.
stack.push(theWords[0]);
// copy the sub-array.
String[] s = new String[theWords.length - 1];
System.arraycopy(theWords, 1, s, 0, theWords.length - 1);
// recurse
return wordReverse(s, stack) + " " + stack.pop();
}
public static String wordReverse(String[] theWords) {
// call the recursive implementation with a new Stack.
return wordReverse(theWords, new Stack<String>());
}
public static void main(String args[]) {
Scanner takeIn = new Scanner(System.in);
String allWords = takeIn.nextLine();
String[] goodWords = allWords.split(" ");
System.out.println(wordReverse(goodWords));
takeIn.close();
}
Works like so
Hello world, goodbye world
world goodbye world, Hello

Related

Finding whether two strings are connected in a Hashmap<String, ArrayList<String>> through recursion?

The question is asking us to find whether a connection between two airlines are possible. For the input code, they give us the list of airlines and then which airlines are connected to which. I was able to read everything into the scanner and make a Hashmap of String values connecting to a String ArrayList, in order to compensate for duplicating keys. There is no issues with the Hashmap, as after reading out all of the keys and the corresponding values in their ArrayList, everything was matching up.
Here is the printed Hashmap below(some airlines are not listed below because they have no connections, ie: southwest):
continental, [america_west, air_china, alaska, air_france, virgin_atlantic]
austrian_airways, [delta]
virgin_atlantic, [air_france]
delta, [swiss_air, austrian_airways, air_canada]
america_west, [mesa, alaska, twa]
The issue is calling the recursion in which, given two Strings of Airlines, find if there is a connection. My recursion below is checking whether there is an initial connection between the Airlines, and it not, recursively go inwards. However the error seems to be a Stack Overflow Error. I do not understand why it would overflow
if the test case gives Airlines {"delta" "america_west"},{"continental" "mesa"},{"southwest" "delta"},{"twa" "air_france"}.
public static boolean recur(String a, String b) {
boolean connection = false;
if(partners.containsKey(a)&&partners.get(a).contains(b)) {return true;}
for(String airlines: (ArrayList<String>)partners.get(a)) {
if(partners.containsKey(airlines))
recur(airlines,b);
}
return connection;
}
Edit:
I'm sorry I didn't include all of the code, it's my first time uploading, and I felt that it was a bit long.
public class airlinePartners{
static Map<String, ArrayList> partners = new HashMap<String, ArrayList>();
static String returnT = "PARTNERS\n";
static String returnF = "No miles for you\n";
int number = 0;
public static void readIn() throws Exception{
Scanner sc = new Scanner(new File("partners.dat"));
String[] temp = new String[2];
int airline = sc.nextInt();
for(int i = 0; i < airline; i++) {
sc.next();
}
int partner = sc.nextInt();
sc.nextLine();
for(int i = 0; i < partner; i++) {
temp = sc.nextLine().split(" ");
ArrayList<String> temps = new ArrayList<String>();
if(partners.containsKey(temp[0])) {
partners.get(temp[0]).add(temp[1]);
}
else {
temps.add(temp[1]);
partners.put(temp[0], temps);
}
}
Iterator<Map.Entry<String, ArrayList>> i = partners.entrySet().iterator();
while(i.hasNext()){String key = i.next().getKey();
System.out.println(key+", "+partners.get(key));
}
int repeat = sc.nextInt();
sc.nextLine();
for(int m = 0; m < repeat;m++) {
temp= sc.nextLine().split(" ");
//System.out.println(temp[0] + " "+ temp[1]);
if(recur(temp[0], temp[1])) {
System.out.println(returnT);
}
else {
System.out.println(returnF);
}
}
}
public static boolean recur(String a, String b) {
boolean connection = false;
if(partners.containsKey(a)&&partners.get(a).contains(b)) {return true;}
for(String airlines: (ArrayList<String>)partners.get(a)) {
if(partners.containsKey(airlines))
recur(airlines,b);
}
return connection;
}
public static void main(String args[]) throws Exception
{
new airlinePartners().readIn();
}
}

How to add String output to an array within a recursion

I am writing a recursive procedure to return a permutation of a string
I get the desired output printed to the console. However, I would like to add the output to an array to be able to work on it further. How can I achieve it?
import java.util.*;
public class Permutation {
public static void main(String args[]) {
permute("A", "BCD");
}
public static void permute(String FirstElement, String Remainder) {
List<String> mylist_tobuild = new ArrayList<String>();
if (Remainder.length() <= 1) {
FirstElement = FirstElement+Remainder;
// System.out.println(FirstElement);
mylist_tobuild.add(FirstElement);
System.out.println(mylist_tobuild);
}
else
for (int i = 0; i < Remainder.length(); i++) {
try {
String newString = Remainder.substring(0, i) + Remainder.substring(i + 1);
permute(FirstElement + Remainder.charAt(i), newString);
} catch (StringIndexOutOfBoundsException exception) {
exception.printStackTrace();
}
}
}
}
I get: [ABCD] [ABDC] [ACBD] [ACDB] [ADBC] [ADCB]
I would like to have: [ABCD, ABDC, ACBD, ACDB, ADBC, ADCB,]
You can supply the List as an argument:
public static void main(String args[]) {
List<String> perms = new ArrayList<>();
permute("A", "BCD",perms);
System.out.println(perms);
}
public static void permute(String FirstElement, String Remainder, List<String> perms) {
if (Remainder.length() <= 1) {
FirstElement = FirstElement+Remainder;
perms.add(FirstElement);
} else {
for (int i = 0; i < Remainder.length(); i++) {
try {
String newString = Remainder.substring(0, i) + Remainder.substring(i + 1);
permute(FirstElement + Remainder.charAt(i), newString, perms);
} catch (StringIndexOutOfBoundsException exception) {
exception.printStackTrace();
}
}
}
}
You are creating a new list every time you go through the permute method. To fix that, you can take your list creation out of the method (e.g. create a static field), so you don't create a new list every time you go through the loop. Then add your print statement after your permutation method in your main class, so you can get the final result.
private static ArrayList<String> mylist_tobuild;
public static void main(String args[]) {
mylist_tobuild = new ArrayList<>(); //initialize list here once
permute("A", "BCD");
System.out.println(mylist_tobuild);
}

Evaluate a prefix expression using stacks

I have to evaluate a prefix expression using stacks, I did it but I don't understand why the code doesn't work properly, it marks 2 bugs when I compile the code, they are:
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at evaluationprefix.EvaluationPreFix.EvaluationPrefix(EvaluationPreFix.java:56)
at evaluationprefix.EvaluationPreFix.main(EvaluationPreFix.java:25)
public class EvaluationPreFix {
public static void main(String[] args) {
Stack st = new Stack();
Scanner sc = new Scanner(System.in);
System.out.println("enter the size of expression");
int t = sc.nextInt();
sc.nextLine();
for (int i = 0; i < t; i++) {
System.out.println("enter an element");
String element = sc.nextLine();
st.push(element);
}
int r = EvaluationPrefix(st); //marks an Error here
System.out.println("Result: " + r);
}
public static int EvaluationPrefix(Stack st) {
Stack st2 = new Stack();
while (!st.isEmpty()) {
Object e = st.pop();
if (e.equals('+')) {
st2.push((Integer) st2.pop() + (Integer) st2.pop());
} else if (e.equals('-')) {
st2.push((Integer) st2.pop() - (Integer) st2.pop());
} else if (e.equals('*')) {
st2.push((Integer) st2.pop() * (Integer) st2.pop());
} else if (e.equals('/')) {
st2.push((Integer) st2.pop() / (Integer) st2.pop());
} else {
st2.push(e);
}
}
return (Integer) st2.pop();//marks an error here
}
}
Changes made:
In the main method, changed the stack, st, to String type.
In the EvaluationPrefix method,
changed the parameter stack to String type.
changed the stack, st2, to Integer type.
changed the arithmetical operators within equals to String.
Here you go,
public class EvaluationPreFix {
public static void main(String[] args) {
//1. parameterized with String
Stack<String> st = new Stack();
Scanner sc = new Scanner(System.in);
System.out.println("enter the size of expression");
int t = sc.nextInt();
sc.nextLine();
for (int i = 0; i < t; i++) {
System.out.println("enter an element");
String element = sc.nextLine();
st.push(element);
}
int r = EvaluationPrefix(st); //marks an Error here
System.out.println("Result: " + r);
}
//2. parameterized with String
public static int EvaluationPrefix(Stack<String> st) {
//3. parameterized with Integer
Stack<Integer> st2 = new Stack();
while (!st.isEmpty()) {
String e = st.pop();
//4. arithmetic sign comparison to string instead
//of character
if (e.equals("+")) {
st2.push(st2.pop() + st2.pop());
} else if (e.equals("-")) {
st2.push(st2.pop() - st2.pop());
} else if (e.equals("*")) {
st2.push(st2.pop() * st2.pop());
} else if (e.equals("/")) {
st2.push(st2.pop() / st2.pop());
} else {
st2.push(Integer.valueOf(e));
}
}
return st2.pop();
}
}
Assuming we are talking about java.util.stack - this is just a Collection storing what you push into it, and you are using it as raw type.
Stack st = new Stack();
That means you can push objects of any type onto this stack. It seems that you only want to store Integers - tell the compiler about that by using generics.
Stack<Integer> st = new Stack<>();
This will tell you that the problem is wherever you try to convert e to an Ìntegerby casting, because in your case, the values ofeare theStrings you pused intostinmain()`.
You should also replace the declaration of st in main with
Stack<String> st = new Stack<>();
and the method declaration to
public static int EvaluationPrefix(Stack<String> st)
to highlight the problem.
When you have a String and want to convert it to an Integer, you need to parse it, for example using Integer.parseInt. But you need to be aware that this method will throw a NumberFormatException if the String is not a number. You will have to handle this exception, for example by catching it and printing a helpful error message.

Java Error; array required, but java.lang.String found

I am currently trying to complete this program and I'm having trouble with this error. I've done many things trying to fix it so I can compile it but it won't work. It seems that the "String alphabet" is getting the error. Can someone help me solve this please?
import java.util.Scanner;
public class Period
{
private static String phrase;
private static String alphabet;
public static void main(String [] args)
{
Scanner keyboard = new Scanner(System.in);
String userInput;
int[] letter = new int [27];
int number = keyboard.nextInt();
System.out.println("Enter a sentence with a period at the end.");
userInput = keyboard.nextLine();
userInput.toLowerCase();
}
public void Sorter(String newPhrase)
{
phrase=newPhrase.substring(0,newPhrase.indexOf("."));
}
private int charToInt(char currentLetter)
{
int converted=(int)currentLetter-(int)'a';
return converted;
}
private void writeToArray()
{
char next;
for (int i=0;i<phrase.length();i++)
{
next=(char)phrase.charAt(i);
sort(next);
}
}
private String cutPhrase()
{
phrase=phrase.substring(0,phrase.indexOf("."));
return phrase;
}
private void sort(char toArray)
{
int placement=charToInt(toArray);
if (placement<0)
{
alphabet[26]=1;
}
else
{
// here is one spot that mainly the error pops up?
alphabet[placement]=alphabet[placement]+1;
}
}
public void entryPoint()
{
writeToArray();
displaySorted();
}
private void displaySorted()
{
for (int q=0; q<26;q++)
{
System.out.println("Number of " + (char)('a'+q) +"'s: "+alphabet[q]);
}
}
}
Your sort method is treating alphabet (the String) as an array. String is not a char[] but you can call String.toCharArray() like
private void sort(char toArray)
{
char[] alpha = alphabet.toLowerCase().toCharArray();
int placement=charToInt(toArray);
if (placement<0)
{
alpha[26]=1;
}
else
{
alpha[placement]=alpha[placement]+1;
}
alphabet = new String(alpha, "UTF-8");
}
But modifying a String is not possible, because they are immutable. For the same reason your raw call alphabet.toLowerCase() doesn't modify the alphabet in your other method.
The variable alphabet is defined as a String data type, but you need to define it as an array if you want to reference it using the bracket notation [] you have in your code. The error message is pretty clear in this case.
String[] example = new String[3];
example[0] = "Hello";
example[1] = "ETC...";

If an input is in the array return true, else false

Fixed it. Working code! I had to move the fruit array into the method and call it from main.
import java.util.Scanner;
public class StringArrayTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input;
System.out.println("Enter a fruit: ");
input = sc.nextLine();
System.out.println("Is \"" + input + "\" in the array? " + isIn(input));
sc.close();
}
public static boolean isIn(String input) {
String[] fruit = new String[6];
fruit[0] = "grape";
fruit[1] = "banana";
fruit[2] = "apple";
fruit[3] = "mango";
fruit[4] = "watermelon";
fruit[5] = "orange";
for(int i = 0; i < fruit.length; i++) {
if (input.equals(fruit[i])) {
return true;
}
}
return false;
}
}
The following code will return true if the array contains the input and false if it doesn't.
Credits to camickr for this code:
Arrays.asList(yourArray).contains(yourString)
return false must be outside the for loop. If it's in the else part, the for loop will end at the first iteration.
Here's how the code should look like:
public boolean isIn(String input) {
for(int i = 0; i < fruit.length; i++) {
if (input.equals(fruit[i])) {
return true;
}
}
return false;
}
Also, you cannot declare a method inside another method. Move the method isIn outside main.
Other problems in your code:
String[] fruit is currently declared, initialized and filled inside main method. It should be at least declared outside as a field of the class in order to be accessed by other methods.
You're not using isIn anywhere.
In order to use the fields and methods inside main method, you have two options:
Declare the fields and methods as static.
Create a new instance of your class inside the main method and use the fields and methods from this instance.
The code may look like this:
import java.util.Scanner;
public class StringArrayTest {
static String[] fruit = new String[6];
public static void main(String[] args) {
fruit[0] = "grape";
fruit[1] = "banana";
fruit[2] = "apple";
fruit[3] = "mango";
fruit[4] = "watermelon";
fruit[5] = "orange";
Scanner sc = new Scanner(System.in);
String input;
input = sc.nextLine();
if (isIn(input)) {
//do something...
} else {
//do something else...
}
}
public static boolean isIn(String input) {
for(int i = 0; i < fruit.length; i++) {
if (input.equals(fruit[i])) {
return true;
}
}
return false;
}
}
Summarizing the suggestions given by others.
import java.util.Arrays;
import java.util.Scanner;
public class StringArrayTest {
public static void main(String[] args) {
String[] fruit = new String [] {"grape", "banana", "apple", "mango", "watermelon", "orange"};
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
System.out.println(Arrays.asList(fruit).contains(input));
}
}

Categories