Java while loop text formatting - java

Inputs
Hi.
Bye.
#
Actual outputs:
h(1)i(1)
Expected outputs:
h(1) i(1)
b(1) e(1) y(1)
There must be a gap between both items. How do I need to modify my while loop so # will indicate stop?
import java.util.Scanner;
public class MyClass {
public static void main(String args[]) {
int a[] = new int[26];
Scanner sc = new Scanner (System.in);
String str = sc.nextLine();
for (char ch : str.toCharArray())
if (ch >= 65 && ch <= 90)
a[ch - 65]++;
else if (ch >= 97 && ch <= 122)
a[ch - 97]++;
for (int i = 0; i < 26; i++)
if (a[i] > 0)
System.out.print((char)(i + 97) + "(" + a[i] + ")");
}
}

First question
Seems you just need to add a space at the end of the print. You have this:
System.out.print( (char)(i+97)+ "(" + a[i]+")");
It should be:
System.out.print( (char)(i+97)+ "(" + a[i]+") "); // Added a space at the end.
Or you could also print the space later:
System.out.print( (char)(i+97)+ "(" + a[i]+")");
System.out.print(" ");
Second question
About the while-loop, you could wrap what you have within the loop and should work, something like:
// This will be used for the initial value ONLY, in your example, it should be the "Hi"
String str = sc.nextLine();
while (!str.equals("#")) {
int a[]=new int[26];
for(int i = 0; i<str.length();i++) {
if(str.charAt(i)>=65 && str.charAt(i)<=90) {
a[str.charAt(i)-65]++;
}
else if(str.charAt(i)>=97 && str.charAt(i)<=122) {
a[str.charAt(i)-97]++;
}
}
for(int i=0;i<26;i++) {
if(a[i]>0) {
System.out.print( (char)(i+97)+ "(" + a[i]+")");
}
}
System.out.println(); // Printing new line to split next output
// This will be for the next inputs you have, in your example: "Bye" and "#"
str = sc.nextLine();
}

The space can be added into the print statement.
The loop can end when user enters # character.
Added one extra println to improve appearance.
import java.util.Scanner;
public class MyClass {
public static void main(String args[]) {
String str = "";
int a[];
Scanner sc = new Scanner(System.in);
while (!(str = sc.nextLine()).equals("#")) {
a = new int[26];
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) >= 65 && str.charAt(i) <= 90) {
a[str.charAt(i) - 65]++;
} else if (str.charAt(i) >= 97 && str.charAt(i) <= 122) {
a[str.charAt(i) - 97]++;
}
}
for (int i = 0; i < 26; i++) {
if (a[i] > 0) {
System.out.print((char) (i + 97) + "(" + a[i] + ") "); // space added
}
}
System.out.println(""); // looks better with this
}
sc.close();
}
}

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

Array out of Bounds? with string split

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

in function findVowels for loop increment doesn't work, only prints the last vowel?

here in the findVowels function I am trying to print every 2nd vowel which I got from outPut function in rev but it just print the last vowel only....
import java.util.Scanner;
public class VowelString {
static char rev;
static String str;
static int count = 0;
void inPut() {
Scanner sc = new Scanner(System.in);
str = sc.nextLine();
System.out.println(str);
sc.close();
}
void outPut() {
System.out.println(str);
// int length=str.length();
try {
for (int i = 0; i <= str.length() - 1; i++) {
if ((str.charAt(i) == 'a') || (str.charAt(i) == 'e')
|| (str.charAt(i) == 'i') || (str.charAt(i) == 'o')
|| (str.charAt(i) == 'u')) {
rev = str.charAt(i);
System.out.print(rev);
count++;
}
}
// System.out.println(rev);
System.out.println("\ntotal " + count);
} catch (IndexOutOfBoundsException e) {
System.out.println(e);
}
}
void findVowels(char word) {
this.rev = word;
String asta = String.valueOf(rev);
for (int i = 0; i <= asta.length() - 1; i = +2) {
char nawa = asta.charAt(i);
System.out.println("something = " + nawa);
}
}
public static void main(String[] args) {
VowelString vS = new VowelString();
vS.inPut();
// System.out.println("Values of Input " + vS);
vS.outPut();
// System.out.println("Values of OutPut " + vS);
vS.findVowels(rev);
}
}
You are only saving the last vowel you find to rev
rev = str.charAt(i);
inside output(). So rev in findVowel will only be 1 char it seems. Perhaps you mean to say
rev += str.charAt(i);
Though this is not recommendable in a general setting it will probably suffice for your problem unless you have huge Strings.
The posted code should print all vowels. Not only the last as you say. But also not every 2nd as you want. It's also poorly written. Here's one way to print every second vowel, and a bit better written overall:
for (int i = 0, count = 0; i < str.length(); i++) {
char c = str.charAt(i);
switch (c) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
count++;
if (count % 2 == 0) {
System.out.print(c);
}
break;
}
}

why is indexof not working?

I have a program for a hangman game and the indexof is not working for me? its on line 30. I have been trying to figure it out but I cannot.if (guessedWord.indexOf(letter) >= 0). I will keep trying to find out what I did wrong
import java.io.PrintStream;
import java.util.Scanner;
public class Hangman
{
public static void main(String[] args)
{
String[] words = { "write", "program", "that", "receive", "positive" };
Scanner input = new Scanner(System.in);
char anotherGame;
do
{
int index = (int)(Math.random() * words.length);
String hiddenWord = words[index];
StringBuilder guessedWord = new StringBuilder();
for (int i = 0; i < hiddenWord.length(); i++) {
guessedWord.append('*');
}
int numberOfCorrectLettersGuessed = 0; int numberOfMisses = 0;
while (numberOfCorrectLettersGuessed < hiddenWord.length()) {
System.out.print("(Guess) Enter a letter in word " + guessedWord +
" > ");
String s = input.nextLine();
char letter = s.charAt(0);
if (guessedWord.indexOf(letter) >= 0) {
System.out.println("\t" + letter + " is already in the word");
} else if (hiddenWord.indexOf(letter) < 0) {
System.out.println("\t" + letter + " is not in the word");
numberOfMisses++;
} else {
int k = hiddenWord.indexOf(letter);
while (k >= 0) {
guessedWord.setCharAt(k, letter);
numberOfCorrectLettersGuessed++;
k = hiddenWord.indexOf(letter, k + 1);
}
}
}
System.out.println("The word is " + hiddenWord + ". You missed " + numberOfMisses + (numberOfMisses <= 1 ? " time" : " times"));
System.out.print("Do you want to guess for another word? Enter y or n> ");
anotherGame = input.nextLine().charAt(0);
}while (anotherGame == 'y');
}
}
You are passing in a char where String is expected. Try using String.valueOf(letter) like this:
if (guessedWord.indexOf(String.valueOf(letter)) >= 0) {
// Your code
}
StringBuilder#indexOf(char) is undefined. You could do
if (guessedWord.indexOf(Character.toString(letter)) >= 0) {
there's no indexOf(char) method for a StringBuilder.
guessedWord.indexOf(letter)
should be
if (guessedWord.toString().indexOf(letter) >= 0) {

Categories