Reversing strings in Java (loops) until "done" - java

this is a lab for class I'm trying to do. Here's the instructions:
Write a program that takes in a line of text as input, and outputs that line of text in reverse. The program repeats, ending when the user enters "Done", "done", or "d" for the line of text.
Ex: If the input is:
"Hello there
Hey
done"
the output is:
"ereht olleH
yeH"
And here's what I have right now:
public class LabProgram {
public static void main(String[] args) {
/* Type your code here. */
Scanner scnr = new Scanner(System.in);
String[] inputs = new String[100];
String input;
int i = 0;
while (true) {
input = scnr.nextLine();
if(input.equals("Done") || input.equals("done") || input.equals("d"))
break;
inputs[i] = input;
i++;
}
for (int j = 0; j < i; j++) {
int length = inputs[j].length();
String reverse = "";
for (int k = length - i; k >= 0; k--) {
reverse = reverse + inputs[j].charAt(k);
}
System.out.print("\n" + reverse);
}
}
}
Current output
What am I doing wrong??

Iterate through the array, and reverse elements at every index.
This solution is time consuming but does your job
for (int j = 0; j < inputs.lenght; j++) {
int length = inputs[j].length();
char a;
String rev = "";
for(int i =0; i< length; i++){
a = inputs[j].charAt(i);
rev = a + rev;
}
System.out.println(rev);
}

*Try to use StringBuilder And use method reverse -- #Artur Todeschini
To add to what Artur said, an ArrayList of StringBuilders could do the trick quite well:
for(StringBuilder nextEntry : stringBuilderList)
{
nextEntry.reverse();
}
The enhanced for-loop will go through each entry in the ArrayList, and the StringBuilder's reverse will change the order of the letters.
EDIT TO SHOW FORMATTING
ArrayList<StringBuilder> stringBuilderList= new ArrayList<>();
*note. given that this is for a lab, its probably for learning purposes and using built-in classes that does all the work for you are usually not the intended solution. -- #experiment unit 1998X

Try to use StringBuilder
And use method reverse

This is another "ArrayList and StringBuilder-less" version.
Create two Strings, one filled and one empty:
String nextString = stringArray[i],
template = new String();
Loop through the length of the String, adding the next character in from the end each time through.
int length = nextString.length() - 1;
for(int j = 0; j < length; j++)
{
template += nextString.charAt(length - j);
}
Add the whole String to the String array's index
stringArray[i] = template;
NOTE
This is an inner loop for a String array and is NOT complete code

Related

How can I create all vowel combinations of a String and add each combination to an ArrayList

I'm having trouble printing off all vowel combinations of a given input. My input is "SOMETHING" and I would like to print off all vowel combinations such as sxmxthxng where x is aeiou vowels. I believe my problem is that I find a vowel, change it with all the others vowels and move on. I need to continue down the rest of the word and find additional vowels and change those before proceeding.
Other refs
vowelList is an ArrayList containing all lower case vowels.
Code
private static void createVowelCombos(String word) {
Set<String> rmRepeats = new HashSet<>();
StringBuilder sbAddWord = new StringBuilder(word);
String[] splitWord = word.split("");
for (int i = 0; i < word.length(); i++) {
// System.out.println("real word: " + splitWord[i]);
if (splitWord[i].matches(".*[aeiou]")) {
// System.out.println("Split: " + splitWord[i]);
for (int j = 0; j < 5; j++) {
sbAddWord.setCharAt(i, vowelList.get(j).charAt(0));
System.out.println(sbAddWord.toString());
}
}
}
}
Sample Output with input "SOMETHING"
samething
semething
simething
something
sumething
sumathing
sumething
sumithing
sumothing
sumuthing
sumuthang
sumutheng
sumuthing
sumuthong
sumuthung
For some reason it is giving me all the combinations with 'u' but not the other vowels. I would like to get all the results for the other vowels as well.
as already suggested your problem can be best solved by using recursion (with backtracking). I've modified your code so as to print the required output. Have a look !!
private static void createVowelCombos(String word, int start) {
StringBuilder sbAddWord = new StringBuilder(word);
String[] splitWord = word.split("");
if(start==splitWord.length)
{
System.out.println(word);
return;
}
if (splitWord[start].matches(".*[aeiou]")) {
// System.out.println("Split: " + splitWord[i]);
for (int j = 0; j < 5; j++) {
sbAddWord.setCharAt(start, vowelList.get(j).charAt(0));
createVowelCombos(sbAddWord.toString(),start+1);
//System.out.println(sbAddWord.toString());
}
}
else
createVowelCombos(sbAddWord.toString(),start+1);
}
Call createVowelCombos("something",0) from the calling method.

What should I do to fix this scanner-related bug?

Even though this code compiles:
import java.util.Scanner; // imports the Scanner class from the java.util package
public class ScannerPractice {
public static void main(String args[]) {
Scanner word = new Scanner("word 1 2 3 4"); // creates a new Scanner objecrt with a string as its input
String scaStr = word.nextLine(); // converts scanner to string
String strArr[] = new String[10];
// as long as the scanner has another character...
for (int i = 0; i < scaStr.length(); i++) {
int j = 0;
String k = "";
// if the next token is an integer...
if (word.hasNextInt()) {
j = word.nextInt();
k = String.valueOf(j);
strArr[i] = k;
}
// otherwise, skip over that token
else {
word.next();
}
}
String k = "";
// for each character in charArr
for (int i = 0; i < strArr.length; i++) {
// Accumulate each element of charArr to k
k += " " + strArr[i];
}
System.out.print(k);
}
}
I get this error:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at ScannerPractice.main(ScannerPractice.java:28)
The exception refers to line 28, which is:
word.next();
I have tried looking at my for loop that assigns values to the string array, but I still couldn't find the error.
I am racking my brain trying to solve this. Even a hint would be most appreciated.
You already consumed all the strings in your Scanner on this line.
String scaStr = word.nextLine();
So, the scanner doesn't have more characteres and that's why you are getting that error.
I think you don't need to 'convert your scanner to string' in order to iterate over it. You can simply use a while to check if your Scanner has remaining characteres.
while(word.hasNext()) {
int j = 0;
String k = "";
// if the next token is an integer...
if (word.hasNextInt()) {
j = word.nextInt();
k = String.valueOf(j);
strArr[i] = k;
}
// otherwise, skip over that token
else {
word.next();
}
}
Change the loop to check whether the scanner has any more input:
Scanner word = new Scanner("word 1 2 3 4");
String strArr[] = new String[10];
int i = 0;
while (word.hasNext()) {
int j = 0;
String k = "";
if (word.hasNextInt()) {
j = word.nextInt();
k = String.valueOf(j);
strArr[i] = k;
}
else {
word.next();
}
}
It doesn't make sense to iterate over the string you already consumed from the scanner, because then you lose the ability to match tokens. If you wanted to use a string tokenizer you could do that, but then you can drop using the scanner.
If you want your code to run correctly change the input to:
Scanner word = new Scanner("word"+"\n"+"1"+"\n"+"2"+"\n"+"3"+"\n"+"4");
adding newline character solves the problem.

Extract words from an array of Strings in java based on conditions

I am trying to do an assignment that works with Arrays and Strings. The code is almost complete, but I've run into a hitch. Every time the code runs, it replaces the value in the index of the output array instead of putting the new value in a different index. For example, if I was trying to search for the words containing a prefix "b" in the array of strings, the intended output is "bat" and "brewers" but instead, the output comes out as "brewers" and "brewers". Any suggestions? (ps. The static main method is there for testing purposes.)
--
public static void main(String[] args) {
String[] words = {"aardvark", "bat", "brewers", "cadmium", "wolf", "dastardly", "enigmatic", "frenetic",
"sycophant", "rattle", "zinc", "alloy", "tunnel", "nitrate", "sample", "yellow", "mauve", "abbey",
"thinker", "junk"};
String prefix = "b";
String[] output = new String[wordsStartingWith(words, prefix).length];
output = wordsStartingWith(words, prefix);
for (int i = 0; i < output.length; i++) {
System.out.println("Words: " + i + " " + output[i]);
}
}
public static String[] wordsStartingWith(String[] words, String prefix) {
// method that finds and returns all strings that start with the prefix
String[] returnWords;
int countWords = 0;
for (int i = 0; i < words.length; i++) {
// loop to count the number of words that actually have the prefix
if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
countWords++;
}
}
// assign length of array based on number of words containing prefix
returnWords = new String[countWords];
for (int i = 0; i < words.length; i++) {
// loop to put strings containing prefix into new array
for (int j = 0; j < returnWords.length; j++) {
if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
returnWords[j] = words[i];
}
}
}
return returnWords;
}
--
Thank You
Soul
Don't reinvent the wheel. Your code can be replaced by this single, easy to read, bug free, line:
String[] output = Arrays.stream(words)
.filter(w -> w.startsWith(prefix))
.toArray(String[]::new);
Or if you just want to print the matching words:
Arrays.stream(words)
.filter(w -> w.startsWith(prefix))
.forEach(System.out::println);
Its because of the code you have written. If you would have thought it properly you would have realized your mistake.
The culprit code
for (int j = 0; j < returnWords.length; j++) {
if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
returnWords[j] = words[i];
}
}
When you get a matching word you set whole of your output array to that word. This would mean the last word found as satisfying the condition will replace all the previous words in the array.
All elements of array returnWords gets first initialized to "bat" and then each element gets replaced by "brewers"
corrected code will be like this
int j = 0;
for (int i = 0; i < words.length; i++) {
if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
returnWords[j] = words[i];
j++;
}
}
Also you are doing multiple iterations which is not exactly needed.
For example this statement
String[] output = new String[wordsStartingWith(words, prefix).length];
output = wordsStartingWith(words, prefix);
can be rectified to a simpler statement
String[] output = wordsStartingWith(words, prefix);
The way you're doing this is looping through the same array multiple times.
You only need to check the values once:
public static void main(String[] args) {
String[] words = {"aardvark", "bat", "brewers", "cadmium", "wolf", "dastardly", "enigmatic", "frenetic",
"sycophant", "rattle", "zinc", "alloy", "tunnel", "nitrate", "sample", "yellow", "mauve", "abbey",
"thinker", "junk"};
String prefix = "b";
for (int i = 0; i < words.length; i++) {
if (words[i].toLowerCase().startsWith(prefix.toLowerCase())) {
System.out.println("Words: " + i + " " + words[i]);
}
}
}
Instead of doing two separate loops, try just having one:
String[] returnWords;
int[] foundWords = new int[words.length];
int countWords = 0;
for (int i = 0; i < words.length; i++) {
// loop to count the number of words that actually have the prefix
if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
foundWords[index] = words[i];
countWords++;
}
}
// assign length of array based on number of words containing prefix
returnWords = new String[countWords];
for (int i = 0; i < countWords; i++) {
returnWords[i] = foundWords[i];
}
My method has another array (foundWords) for all the words that you found during the first loop which has the size of words in case every single word starts with the prefix. And index keeps track of where to place the found word in foundWords. And lastly, you just have to go through the countWords and assign each element to your returnWords.
Not only will this fix your code but it will optimize it so that it will run faster (very slightly; the bigger the word bank is, the greater fast it will search through).

Array out of bounds in Java?

I'm trying to run this code but I keep getting an out of bounds error. This is just the sub class for the super class "Simpler." The user enters in a string then the string is broken down into a char array. The array should not be smaller than the string yet I am getting this error. Can you tell me what I'm doing wrong? Thanks!
import java.util.*;
public class Encrypt extends Simpler
{
public void encryption()
{
boolean loop = true;
while(loop==true)
{
Scanner scan = new Scanner(System.in);
System.out.println("Please enter the phrase you'd like to encrypt: ");
String inPhrase = scan.nextLine();
char[] chars = inPhrase.toCharArray();
char tempArray[] = new char[chars.length+1];
tempArray = chars;
chars = new char[tempArray.length];
for (int i = inPhrase.length(); i<inPhrase.length(); i--)
{
if(chars[i]=='a')
{
chars[i]='1';
}
else if(chars[i]=='b')
{
chars[i]='2';
}
else if(chars[i]=='c')
{
chars[i]='3';
}
else if(chars[i]=='d')
{
chars[i]='4';
}
else if(chars[i]=='z')//I skipped some lines here for convienence
{
chars[i]='{';
}
else if(chars[i]==' ')
{
chars[i]='}';
}
}
String outPhrase = new String(chars);
System.out.println(outPhrase);
}
}
}
I think your for loop statement should look like this:
for (int i = 0; i < inPhrase.length(); i++)
if you're counting up, and like this:
for (int i = inPhrase.length() - 1; i >= 0; i--)
if you're counting down.
update
On looking back over it, I think there is more to it than that though.
I think your code needs to be rewritten:
String inPhrase = scan.nextLine();
char[] chars = inPhrase.toCharArray();
char tempArray[] = new char[chars.length()];
for (int i = 0; i < chars.length(); i++)
{
if(chars[i]=='a')
{
tempArray[i]='1';
}
.
.
.
.
}
String outPhrase = new String(tempArray);
No stop condition in the for loop, in this line:
for (int i = inPhrase.length(); i<inPhrase.length(); i--)
i gets 1, 0, -1, ... and wouldn't stop if -1 wouldn't throw an out of bounds exception
In for loop just changing the condition from i < inPhrase.length() to i >= 0 will do the job.
First thing:
for (int i = inPhrase.length(); i<inPhrase.length(); i--)
you never enter your loop because you assign i = n & entry condition is i < n.
it should be
for (int i = inPhrase.length()-1; i>=0; i--)
Now, this also removes your arrayoutofbound exception because earlier, you tried to access chars[n] which is actually the n+1 th character of that array.

how to revearse a string?

Cant seem to get this to work. trying to get it to read backwards like a mirror without using the buffer class.
public static void main(String[] args) {
Scanner keyboard = new Scanner(System. in);
System.out.println("Enter a phrase:");
String phrase = keyboard.nextLine();
String Rphrase;
int n = phrase.length();
int r = 0;
do{
n--; r++;
Rphrase[r] = phrase[n];
}while(n >= 0);
System.out.println(Rphrase);
I have provided 4 ways of getting the output of the String reversed.
Option 1:
Just iterate the String backwards.
for (int i=phrase.length()-1; i>-1; i--) {
System.out.print(foo.charAt(i));
}
Option 2:
If you would like to put it in the other buffer you can do:
char[] buffer = new char[phrase.length()];
index = 0;
for (int i=phrase.length()-1; i>-1; i--) {
buffer[index++] = foo.charAt(i);
}
Option 3:
You said you didnt want to use the buffer class (which I think you're referring to StringBuffer so I'm assuming you dont want to use StringBuilder either) so here is how you can do it strictly with Strings (which is rather inefficient, because a new String is constructed each iteration):
String foo = "";
for (int i=phrase.length()-1; i>-1; i--) {
foo += foo.charAt(i);
}
Option 4:
A most likely more efficient way of doing this though, is by using StringBuilder:
StringBuilder sb = new StringBuilder(foo.length());
for (int i=foo.length()-1; i>-1; i--) {
sb.append(foo.charAt(i));
}
String reverse = sb.toString();
OR
Refer to this for very simple String reversal with a StringBuilder:
Reverse a string in Java
Try:
public static void main(String[] args) {
Scanner keyboard = new Scanner(System. in);
System.out.println("Enter a phrase:");
String phrase = keyboard.nextLine();
String rPhrase = "";
for (int i = phrase.length() - 1; i >= 0; i--)
rPhrase += phrase.charAt(i);
System.out.println(rPhrase);
}
This is what you need.
String reverse = "";
String toReverse = "hello";
for(int i = 0; i<toReverse.length();i++){
reverse += toReverse.substring(i,i+1);
}
System.out.println(reverse);
Some hints, rather than a complete solution...
Your loop will run for one more iteration when n = 0, which will lead to trying to access index -1. So perhaps try n > 0 as your condition.
And what would happen if the string is empty? It would also try to access index -1, before ever getting to the loop. Perhaps you should put the condition at the beginning.
String doesn't support the [] operator - try:
Rphrase += phrase.charAt(n);
In which case you may as well get rid of r.
you have to make a decrement so it can read its value back to front
for (int i = name.length() - 1, j = 0; i >= 0; i--, j++) {
newName[j] = name.charAt(i); enter code here
}
System.out.println(newName);
}
Simply use StringBuilder.reverse
str = new StringBuilder(str).reverse().toString();

Categories

Resources