Array out of Bounds? with string split - java

Array out of bounds ? i'm trying to perform the output in the picture:
Using this INPUT
"JAVA IS A PROGRAMMING LANGUAGE"
This is my code so far
import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Input Phrase:");
String s = in.nextLine();
String[] word=s.split(" ");
String rts=" ";
for(int i=0;i<word.length;i++){
if(word[i].length()>=rts.length()){
rts=word[i];
}
}
int thisislength = rts.length();
for (int a = 0; a < thisislength ;a++ ) {
for (int b = 0; b < word.length ;b++ ) {
System.out.print(word[b].charAt(a)+" ");
}
System.out.println();
}
}
}
When the second word reaches its last letter it doesn't continue the for loop, is there any way to continue the loop even if the second word reaches its max length.

< should have been <=. Reversing left and right hand sides makes it more readably I think.
for (int a = 0; a < thisislength; a++) {
System.out.printf("%3d ", a+1);
for (int b = 0; b < word.length; b++) {
if (a >= word[b].length()) {
System.out.print(' ');
} else {
System.out.print(word[b].charAt(a));
}
System.out.print(' ');
}
System.out.println();
}
Or instead of the if-else statement:
for (String w : word) {
System.out.print(a >= w.length() ? ' ' : w.charAt(a));
}

This gives the result you want:
for (int a = 0; a < thisislength ;a++ ){
for (int b = 0; b < word.length ;b++ ){
if(word[b].length() < a + 1){
System.out.print(" ");
}else{
System.out.print(word[b].charAt(a) + " ");
}
}
System.out.println();
}
This line was changed:
if(word[b].length() < a + 1) and not if(word[b].length() < a)
and 2 spaces print in the if statement

TRY THIS SOLUTION HOPE IT WILL HELP YOU :
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
// GET VALUE FROM THE CONSOLE
Scanner in = new Scanner(System.in);
System.out.print("Input Phrase:");
String s = in.nextLine();
// SPLIT STRING TO WORDS
String[] words = s.split(" ");
// CREATE A LIST OF CHAR_ARRAY CALLED : matrix
List<char[]> matrix = new ArrayList<char[]>();
// REFERENCE THE LARGEST WORD IN WORDS ARRAY EX : PROGRAMMING IS THE LARGEST
int max = 0;
// FILL OUR LIST OF ARRAY OF CHARS
for (int b = 0; b < words.length ;b++ ) {
char[] chars = words[b].toCharArray();
max = (chars.length >= max)? chars.length : max ;
matrix.add( chars );
}
// PRINT OUR CHAR
for (int a = 0; a < max ;a++ ) {
for (int b = 0; b < words.length ;b++ ) {
if(a < matrix.get(b).length) {
System.out.print(matrix.get(b)[a]);
System.out.print(" ");
}else {
System.out.print(" ");
System.out.print(" ");
}
}
System.out.println("");
}
}
}

Related

Can this lengthy if-else Java code be improved by using arrays?

I'm trying to simplify this Java code by adding arrays, but I'm having difficulty.
The code that I have so far that works:
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Homework4A {
public static void main(String[] args) throws FileNotFoundException {
Scanner scan = new Scanner(System.in);
System.out.print("Enter name of the input file: ");
String fileName = scan.next();
try (Scanner inFile = new Scanner(new FileReader(fileName))) {
char number0 = '0';
char number1 = '1';
char number2 = '2';
char number3 = '3';
char number4 = '4';
char number5 = '5';
char number6 = '6';
char number7 = '7';
char number8 = '8';
char number9 = '9';
int count0 = 0;
int count1 = 0;
int count2 = 0;
int count3 = 0;
int count4 = 0;
int count5 = 0;
int count6 = 0;
int count7 = 0;
int count8 = 0;
int count9 = 0;
while (inFile.hasNextLine()) {
String line = inFile.nextLine();
for (int i = 0; i < line.length(); i++) {
if (line.charAt(i) == number0) {
count0++;
}
else if (line.charAt(i) == number1) {
count1++;
}
else if (line.charAt(i) == number2) {
count2++;
}
else if (line.charAt(i) == number3) {
count3++;
}
else if (line.charAt(i) == number4) {
count4++;
}
else if (line.charAt(i) == number5) {
count5++;
}
else if (line.charAt(i) == number6) {
count6++;
}
else if (line.charAt(i) == number7) {
count7++;
}
else if (line.charAt(i) == number8) {
count8++;
}
else if (line.charAt(i) == number9) {
count9++;
}
}
}
System.out.println("\n-= Count of Thistles in =-");
System.out.println("-= the Hundred Acre Wood =-\n");
System.out.println(" -----------");
System.out.println(" type count");
System.out.println(" -----------");
System.out.println(" 0 " + count0);
System.out.println(" 1 " + count1);
System.out.println(" 2 " + count2);
System.out.println(" 3 " + count3);
System.out.println(" 4 " + count4);
System.out.println(" 5 " + count5);
System.out.println(" 6 " + count6);
System.out.println(" 7 " + count7);
System.out.println(" 8 " + count8);
System.out.println(" 9 " + count9);
System.out.println(" -----------");
}
}
}
However, it's kind of a brute-force attack. The spot of difficulty I'm running into is figuring out where to create and pass arrays. Since the code has to read the external file, should the arrays be created and passed in the while statement?
For further reference, the text file that is being read looks like this:
Thistle Map
The goal is to count the occurrences of digits only.
As you stated, you could use arrays.
I would suggest 2 arrays
One to hold the digits to catch
Second one for the counts
Initialization of the arrays
char[] numbers = new char[10];
//initialize of numbers(char) to count
for(int i = 0; i < numbers.length; i++) {
numbers[i] = (char) ('0' + i);
}
int[] counts = new int[10]; //no initialization needed because int is default 0
In the for-loop where you iterate over the line, add a nested for loop, that iterates over the numbers-array. Here is the whole while loop:
while (inFile.hasNextLine()) {
String line = inFile.nextLine();
for (int i = 0; i < line.length(); i++) {
for(int j = 0; j < numbers.length; j++) {
if(line.charAt(i) == numbers[j]) {
counts[j]++;
}
}
}
}
For the output just use another for over the arrays:
for(int i = 0; i < numbers.length; i++) {
System.out.println(" "+ numbers[i] +" " + counts[i]);
}
Edit: Another solution using a Map
//...
Map<Character, Integer> charCounts = new HashMap<>();
for (int i = 0; i < 10; i++) {
charCounts.put((char) ('0' + i), 0);
}
while (inFile.hasNextLine()) {
String line = inFile.nextLine();
for (int i = 0; i < line.length(); i++) {
charCounts.computeIfPresent(line.charAt(i), (key, val) -> val + 1);
}
}
//...
for (Character number : charCounts.keySet()) {
System.out.println(" " + number + " " + charCounts.get(number));
}
With this solution you can easily extend your program to count any occuring character. Just remove the initialization of the map and add this line below the computeIfPresent.
charCounts.putIfAbsent(line.charAt(i), 1);
With Java 8 you can use Files.lines to get a Stream of all the lines in a file.
Then you can transform the stream to a stream over every char using flatMap and in the end collect it to a map that has the Character as key and the count of the character as value.
try (Stream<String> stream = Files.lines(Paths.get(fileName)) {
Map<Character, Long> charCountMap = stream
.flatMap(line -> line.chars().mapToObj(c -> (char) c))
.collect(Collectors.groupingBy(c -> c, Collectors.counting()));
System.out.println(" 0 " + charCountMap.getOrDefault('0', 0));
} catch (IOException e) {
e.printStackTrace();
}
Probably the way I would do it in a real world scenario, because it's short, but just for practice the other answers are better.
Yes. I would say it can be simplified a great deal with an array. You don't need seperate sentinels for the values, you can check they are in range and then use Character.digit to parse them. Something like,
Scanner scan = new Scanner(System.in);
System.out.print("Enter name of the input file: ");
String fileName = scan.next();
try (Scanner inFile = new Scanner(new FileReader(fileName))) {
int[] count = new int[10];
while (inFile.hasNextLine()) {
String line = inFile.nextLine();
for (int i = 0; i < line.length(); i++) {
if (line.charAt(i) >= '0' && line.charAt(i) <= '9') {
count[Character.digit(line.charAt(i), 10)]++;
}
}
}
System.out.println("\n-= Count of Thistles in =-");
System.out.println("-= the Hundred Acre Wood =-\n");
System.out.println(" -----------");
System.out.println(" type count");
System.out.println(" -----------");
for (int i = 0; i < count.length; i++) {
System.out.printf(" %d %d%n", i, count[i]);
}
System.out.println(" -----------");
}
You can use a single array for this and index notation. Each array index should hold the quantity of digits. Much more clear.
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Homework4A {
public static void main(String[] args) throws FileNotFoundException {
Scanner scan = new Scanner(System.in);
System.out.print("Enter name of the input file: ");
String fileName = scan.next();
try (Scanner inFile = new Scanner(new FileReader(fileName))) {
int[] count = new int[10];
while (inFile.hasNextLine()) {
String line = inFile.nextLine();
for (int i = 0; i < line.length(); i++) {
try {
int c = Character.getNumericValue(line.charAt(i));
count[c] += 1;
} catch (Exception e) { }
}
}
System.out.println("\n-= Count of Thistles in =-");
System.out.println("-= the Hundred Acre Wood =-\n");
System.out.println(" -----------");
System.out.println(" type count");
System.out.println(" -----------");
for (int i = 0; i < 10; i++)
System.out.println(" " + i + " " + count[i]);
System.out.println(" -----------");
}
}
}

java not getting output piglatin

The following is my code for converting all the words of the sentence into PigLatin, ie "Her food is stolen" to "ERHAY OODFAY ISAY OLENSTAY", but the output which I am getting is ERHAY. Any corrections would be appreciated. Thanks.
public class piglatin
{
public void main(String s)
{
s=s.toUpperCase();
s=s+" ";
int l=s.length();
String word="";
int n=0;
int w=0;//no of words in s(loop1)
int wor=0;//no of words loop2
for(int i=0;i<l;i++)
{char c=s.charAt(i);
if(c==' ')
w++;
}
for(int i=0;i<l;i++)
{ char c=s.charAt(i);
int m=s.indexOf(' '); //length of first word
if(i==0)
{ for(int j=0;j<m;j++)
{char c1=s.charAt(j);
if(c1=='A'||c1=='E'||c1=='I'||c1=='O'||c1=='U')
{n=j;//index of first vowel
j=m;}
}
word=s.substring(n,m)+s.substring(0,n);
System.out.print(word+"AY"+" ");
}
if(c==' '&&wor!=w-1)
{ s=s.substring(m+1,l);
l=s.length();
i=0;
wor++;
}
if(wor==w-1)
i=l+1;
}
}
}
You can simplify it greatly by splitting the sentence on whitespace and processing each word of the resulting array.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter a sentence: ");
String s = scanner.nextLine();
s = s.toUpperCase();
String[] words = s.split("\\s+");// Split s on whitespace
// Process each word from words[]
for (String word : words) {
int m = word.length(), j;
for (j = 0; j < word.length(); j++) {
char c1 = word.charAt(j);
if (c1 == 'A' || c1 == 'E' || c1 == 'I' || c1 == 'O' || c1 == 'U') {
break;
}
}
String translated = word.substring(j, m) + word.substring(0, j);
System.out.print(translated + "AY" + " ");
}
}
}
A sample run:
Enter a sentence: Her food is stolen
ERHAY OODFAY ISAY OLENSTAY
Alternatively, in addition to using String#indexOf​(int ch), you can use String#indexOf​(String str, int fromIndex) to get all the words of the sentence.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter a sentence: ");
String s = scanner.nextLine();
s = s.toUpperCase();
// Start from index, 0
int fromIndex = 0, lastPositionOfWhitespace = -1;
for (int i = 0; i < s.length(); i++) {
int indexOfWhitespace = s.indexOf(' ', fromIndex);
String word = "";
if (indexOfWhitespace != -1) {
lastPositionOfWhitespace = indexOfWhitespace;
word = s.substring(fromIndex, indexOfWhitespace);
fromIndex = indexOfWhitespace + 1;
} else {
word = s.substring(lastPositionOfWhitespace + 1);// Last word of the sentence
i = s.length();// To stop further processing of the loop with counter, i
}
int m = word.length(), j;
for (j = 0; j < word.length(); j++) {
char c1 = word.charAt(j);
if (c1 == 'A' || c1 == 'E' || c1 == 'I' || c1 == 'O' || c1 == 'U') {
break;
}
}
String translated = word.substring(j, m) + word.substring(0, j);
System.out.print(translated + "AY" + " ");
}
}
}
A sample run:
Enter a sentence: Her food is stolen
ERHAY OODFAY ISAY OLENSTAY

Java String Array, count number of spaces " " [duplicate]

This question already has answers here:
How do I count the number of occurrences of a char in a String?
(48 answers)
Closed 2 years ago.
I am requesting a string from the user. After the user enters their strings a prompt asks if they want to see strings with no, one or more spaces in their strings, then displays the strings.
I am running into issues with counting the spaces in the string. The code provided only counts 1 if there is more than one space in the string. Whole code:
import java.util.*;
import java.util.Scanner;
public class CountSpacesInStrings {
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
String[] array = new String[20];
System.out.println("Please enter anything..., or type QUIT to quit.");
for (int i = 0; i < array.length; i++) {
array[i] = s.nextLine();
boolean result = Arrays.stream(array).anyMatch("QUIT"::equals);
if(result)
{
break;
}
}
String str = null;
int len = -1;
System.out.println("Would you like to display strings with No Spaces, One Space or More? Type No, One, More to see the results: ");
String answer = s.nextLine();
if(answer.equals("No")){
for (int i = 0; i < array.length;i++) {
int count = 0;
if (array[i] != null) {
if (array[i].charAt(i) != ' ') {
count++;
System.out.println(count);
}
}
}
}
else if(answer.equals("One"))
{
for (int i = 0; i < array.length;i++) {
int count = 0;
if (array[i] != null) {
if (array[i].charAt(i) != ' ') {
count++;
System.out.println(count);
}
//System.out.print(array[i] + " ");
}
}
}
else
System.out.println("No values to show");
System.out.println();
}
}
The section I'm looking at is:
if(answer.equals("No")){
for (int i = 0; i < array.length;i++) {
int count = 0;
if (array[i] != null) {
if (array[i].charAt(i) != ' ') {
count++;
System.out.println(count);
}
}
}
Based on the comment of #Pshemo: You would need to add a nested for loop. The second for loop has to iterate through the contents of array[i] (which makes one sentence) and count the number of ' ' characters in that sentence.

Error when transferring code

I'm writing code for class, and the code works fine when I run it in Dr. Java in class. However when I input it for grading, I get an error that reads:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at Main.main(Main.java:247)
at Ideone.assertRegex(Main.java:94)
at Ideone.test(Main.java:42)
at Ideone.main(Main.java:29)
I have no idea what this means, we haven't covered this sort of thing and I am not a very experienced programmer, sorry. My code is as follows;
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int indexFirst = 0;
int indexSecond = 0;
int[] first = new int[10000];
int[] second = new int[10000];
System.out.println("Enter the values for the first array, up to 10000 values, enter a negative number to quit");
do {int value = scanner.nextInt();
if (value < 0) {
break;
}
first[indexFirst++] = value;
} while(true);
System.out.println("Enter the values for the second array, up to 10000 values, enter a negative number to quit");
do {int value = scanner.nextInt();
if (value <= 0) {
break;
}
second[indexSecond++] = value;
} while(true);
System.out.println("First Array:");
for (int i = 0; i < indexFirst; i++) {
System.out.print(first[i] + " ");
}
System.out.println("\n");
System.out.println("Second Array:");
for (int i = 0; i < indexSecond; i++) {
System.out.print(second[i] + " ");
}
System.out.println("\n");
for (int i = 1; i < indexFirst; i++) {
if (first[i-1] > first[i] ) {
System.out.println("ERROR: Array not in correct order");
return;
}
}
for (int i = 1; i < indexSecond; i++) {
if (second[i-1] > second[i] ) {
System.out.println("ERROR: Array not in correct order");
return;
}
}
int[] merged = new int[indexFirst + indexSecond];
int curIdx1 = 0;
int curIdx2 = 0;
for(int mergedIdx = 0; mergedIdx < merged.length; mergedIdx++) {
if (curIdx2 == indexSecond) {
merged[mergedIdx] = first[curIdx1++];
} else if (curIdx1 == indexFirst) {
merged[mergedIdx] = second[curIdx2++];
} else if (first[curIdx1] < second[curIdx2]) {
merged[mergedIdx] = first[curIdx1++];
} else {
merged[mergedIdx] = second[curIdx2++];
}
}
System.out.println("Merged Array:");
for (int i = 0; i < merged.length; i++) {
System.out.print(merged[i] + " ");
}
}
}
If anyone has any input on how to fix this, it would be much appreciated.

Hangman wrong guesses not printing correctly

I have this Hangman program that i am working on for school and i cant get the number of wrong guesses to print correctly when the user guesses a wrong letter. Here is my code that i got so far, i would appreciate any tips.
import java.util.Scanner;
public class HangmanTest {
public static void main(String[] args) {
String[] wordBank = { "madelynn", "crystal", "mcbride", "daughter",
"adorable", "beautiful", "andrew", "programming", "alyssa",
"computers", "mcbreezy", "maddy", "happy", "vacation", "beach",
"java", "benefical", "military", "veteran", "standale",
"lions", "tigers", "redwings", "pistons", "michigan",
"football", "baseball", "hockey", "basketball", "golf" };
int minimum = 0;
int maximum = wordBank.length - 1;
String again;
do {
int choice = minimum + (int) (Math.random() * maximum);
String word = wordBank[choice];
// Converts the random word to asterix
String userWord = "";
for (int i = 0; i < word.length(); i++) {
userWord += "*";
}
// Breaks into a bunch of characters
char[] userWordCh = userWord.toCharArray();
// Show the random word
System.out.println("The word for you to guess is " + userWord);
// instantiate a scanner object
Scanner input = new Scanner(System.in);
int size = word.length();
int rightGuesses = 0;
int wrongGuesses = 0;
while (size != rightGuesses) {
System.out.println("Enter a character: ");
String response = input.next();
char ch = response.charAt(0);
char[] wordChars = word.toCharArray();
for (int i = 0; i < word.length(); i++) {
if (wordChars[i] == ch) {
userWordCh[i] = ch;
++rightGuesses;
} else {
++wrongGuesses;
}
} // end of for loop
System.out.print("The word is: ");
for (int j = 0; j < userWordCh.length; j++)
System.out.print(userWordCh[j]);
System.out.println();
} // end of while loop
System.out.println("You had " + wrongGuesses + " wrong guesses.");
System.out.println("Would you like to play again y/n: ");
again = input.next();
} while (again.equals("y"));
}
}
for (int i = 0; i < word.length(); i++) {
if (wordChars[i] == ch) {
userWordCh[i] = ch;
++rightGuesses;
} else {
++wrongGuesses;
}
} // end of for loop
In this loop, you increment rightGuesses by 1 every time the guess matches a letter in the word, and wrongGueeses by 1 every time the guess does not match a letter in the word. As you can imagine, this will lead to the numbers, collectively, being incremented by the same number as the number of letters, when it should only be incremented once.
Try something like:
boolean foundMatch = false;
for (int i = 0; i < word.length(); i++) {
if (wordChars[i] == ch) {
userWordCh[i] = ch;
if (!foundMatch)
{
++rightGuesses;
foundMatch = true;
}
}
}
if (!foundMatch)
{
++wrongGuesses;
}
// end of for loop
Now we only increment one of rightGuesses and wrongGuesses once - rightGuesses can only be incremented if we have not found a match (setting found match to true), and wrongGuesses can only be incremented once if we have not found a match.
problem is in your for loop. You are iterating over each letter, and for every letter that doesn't match yours, you mark it as an incorrect guess. It should only be marked incorrect if NONE of the letters are correct. Additionally it should only be marked right if you haven't marked it already.
import java.util.Scanner;
import java.util.ArrayList;
public class HangmanTest {
public static void main(String[] args) {
String[] wordBank = { "madelynn", "crystal", "mcbride", "daughter",
"adorable", "beautiful", "andrew", "programming", "alyssa",
"computers", "mcbreezy", "maddy", "happy", "vacation", "beach",
"java", "benefical", "military", "veteran", "standale",
"lions", "tigers", "redwings", "pistons", "michigan",
"football", "baseball", "hockey", "basketball", "golf" };
int minimum = 0;
int maximum = wordBank.length - 1;
String again;
do {
int choice = minimum + (int) (Math.random() * maximum);
String word = wordBank[choice];
// Converts the random word to asterix
String userWord = "";
for (int i = 0; i < word.length(); i++) {
userWord += "*";
}
String guessedLetters="";
// Breaks into a bunch of characters
char[] userWordCh = userWord.toCharArray();
// Show the random word
System.out.println("The word for you to guess is " + userWord);
// instantiate a scanner object
Scanner input = new Scanner(System.in);
int size = word.length();
int rightGuesses = 0;
int wrongGuesses = 0;
boolean foundLetter;
char[] wordChars = word.toCharArray();
guessLoop:
while (size != rightGuesses) {
System.out.println("Enter a character: ");
String response = input.next();
char ch = response.charAt(0);
foundLetter=false;
for (int i=0;i<guessedLetters.size();i++){
if (ch == guessedLetters.charAt(i)){
System.out.println("Already guessed that letter!");
continue guessLoop;
}
}
guessedLetters+=response;
for (int i = 0; i < word.length(); i++) {
if (wordChars[i] == ch) {
foundLetter=true;
userWordCh[i] = ch;
++rightGuesses;
}
} // end of for loop
if(!foundLetter)
++wrongGuesses;
System.out.print("The word is: ");
for (int j = 0; j < userWordCh.length; j++)
System.out.print(userWordCh[j]);
System.out.println();
} // end of while loop
System.out.println("You had " + wrongGuesses + " wrong guesses.");
System.out.println("Would you like to play again y/n: ");
again = input.next();
} while (again.equals("y"));
}
}
I'm guessing here, but I think this might be wrong:
for (int i = 0; i < word.length(); i++) {
if (wordChars[i] == ch) {
userWordCh[i] = ch;
++rightGuesses;
} else {
++wrongGuesses;
}
} // end of for loop
This will increment the rightGuesses and wrongGuesses variables for each character in the word that matches/doesn't match the inputted character. Instead, you need to set a flag when a character "matches", then check that flag at the end to update rightGuesses and wrongGuesses.
for (int i = 0; i < word.length(); i++) {
if (wordChars[i] == ch) {
userWordCh[i] = ch;
++rightGuesses;
} else {
++wrongGuesses;
}
} // end of for loop
This for loop is causing your problem with wrong guesses, since it will say that a character is a wrong guess even though it is in the word. An option you can do is have some boolean that is switched to true when it finds the letter. That way, when you leave the for loop, you check to see if that value is true. If it isn't, increment the wrong guesses.

Categories