Java String letter counter not working [duplicate] - java

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
This is my code for a program that should count the number of each letter in an inputted string. When I run the program, it says that there is 0 of each letter, no matter what I input. Thanks for the help in advance!
import java.util.Scanner;
public class stringprogram {
public static void stringinputmethod()
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter a String");
String strs = scan.nextLine();
int strslength = strs.length();
int numa = 0;
int numb = 0;
int numc = 0;
int numd = 0;
int nume = 0;
int numf = 0;
int numg = 0;
int numh = 0;
int numi = 0;
int numj = 0;
int numk = 0;
int numl = 0;
int numm = 0;
int numn = 0;
int numo = 0;
int nump = 0;
int numq = 0;
int numr = 0;
int nums = 0;
int numt = 0;
int numu = 0;
int numv = 0;
int numw = 0;
int numx = 0;
int numy = 0;
int numz = 0;
for(int i = 0; i <= strslength; i++)
{
if (strs.substring(i, i) == "a")
{
numa = numa + 1;
}
if (strs.substring(i, i) == "b")
{
numb = numb + 1;
}
if (strs.substring(i, i) == "c")
{
numc = numc + 1;
}
if (strs.substring(i, i) == "d")
{
numd = numd + 1;
}
if (strs.substring(i, i) == "e")
{
nume = nume + 1;
}
if (strs.substring(i, i) == "f")
{
numf = numf + 1;
}
if (strs.substring(i, i) == "g")
{
numg = numg + 1;
}
if (strs.substring(i, i) == "h")
{
numh = numh + 1;
}
if (strs.substring(i, i) == "i")
{
numi = numi + 1;
}
if (strs.substring(i, i) == "j")
{
numj = numj + 1;
}
if (strs.substring(i, i) == "k")
{
numk = numk + 1;
}
if (strs.substring(i, i) == "l")
{
numl = numl + 1;
}
if (strs.substring(i, i) == "m")
{
numm = numm + 1;
}
if (strs.substring(i, i) == "n")
{
numn = numn + 1;
}
if (strs.substring(i, i) == "o")
{
numo = numo + 1;
}
if (strs.substring(i, i) == "p")
{
nump = nump + 1;
}
if (strs.substring(i, i) == "q")
{
numq = numq + 1;
}
if (strs.substring(i, i) == "r")
{
numr = numr + 1;
}
if (strs.substring(i, i) == "s")
{
nums = nums + 1;
}
if (strs.substring(i, i) == "t")
{
numt = numt + 1;
}
if (strs.substring(i, i) == "u")
{
numu = numu + 1;
}
if (strs.substring(i, i) == "v")
{
numv = numv + 1;
}
if (strs.substring(i, i) == "w")
{
numw = numw + 1;
}
if (strs.substring(i, i) == "x")
{
numx = numx + 1;
}
if (strs.substring(i, i) == "y")
{
numy = numy + 1;
}
if (strs.substring(i, i) == "z")
{
numz = numz + 1;
}
}
System.out.println("Number of a's: " + numa + "\n" + "Number of b's: " + numb + "\n" + "Number of c's: " + numc + "\n" + "Number of d's: " + numd + "\n" + "Number of e's: " + nume + "\n" + "Number of f's: " + numf + "\n" + "Number of g's: " + numg + "\n" + "Number of h's: " + numa + "\n" + "Number of i's: " + numi + "\n" + "Number of j's: " + numj + "\n" + "Number of k's: " + numk + "\n" + "Number of l's: " + numl + "\n" + "Number of m's: " + numm + "\n" + "Number of n's: " + numn + "\n" + "Number of o's: " + numo + "\n" + "Number of p's: " + nump + "\n" + "Number of q's: " + numq + "\n" + "Number of r's: " + numr + "\n" + "Number of s's: " + nums + "\n" + "Number of t's: " + numt + "\n" + "Number of u's: " + numu + "\n" + "Number of v's: " + numv + "\n" + "Number of w's: " + numw + "\n" + "Number of x's: " + numx + "\n" + "Number of y's: " + numy + "\n" + "Number of z's: " + numz);
}
public static void main(String[] args)
{
stringinputmethod();
}
}

Correct usage of the substring method:
strs.substring(i, i)
needs to be
strs.substring(i, i + 1)
because the char at lastIndex is not included in the output.
Correct comparison of Strings in Java
Also, as pointed out in the comments to this answer, you are comparing Strings with the == operator.
This will only works as long as both your Strings are the same object. For proper comparison you need to use strs.substring(..).equals()
Proper storing of data
Additionally, as already suggested in a comment to your question, you should start using arrays to save data like this.

Instead of
int numa = 0;
....
int numz = 0;
you should use arrays, or even better Map<Character,Integer>.
strs.substring(i, i) == "a" have two problems:
substring(i, i) creates string from i (inclusive), till i (exclusive) which means it creates empty string ""
this is not how we compare Strings. == may work sometimes if strings are pooled, but for dynamically created strings you need to use equals instead of == because Strings are objects, or even better use charAt(i) to get primitive char which you can be able to compare like strs.charAt(i) == 'a' (notice ' instead of ").
You can also use enhanced for loop on array of characters representing your string to avoid charAt. You should probably also be working on lower case characters as pointed in this comment. So your code can look more like
for (char ch : strs.toLowerCase().toCharArray()){
//do something based on value of `ch`
}

Try this:
It is a little bit shorter than your implementation (which is very good, but still a little bit verbose). Use Java 8 with this code, otherwise it won't compile.
What does it do?
If you understand that a string is nothing more but an array you can iterate over that array and see what kind of value is at the given index. The value at this index is put in a map (remember, a map is a key-value-store). So if you put the Integer 1 in the map where its key is "a", that means "a" occurs 1 time.
By reading the values at the appropriate indexii (very sophisticated plural form of index) with HashMap.get("a") and then incrementing the value by one, we have a nice little letter counter... without the need to predefine numa=0 and so forth. Give it a try and let me know if it werx.
package lettercounter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Scanner;
/**
*
* #author edm
*/
public class LetterCounter {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter a String");
String strs = scan.nextLine();
//this map will be populated with the occurrence of the letters in the string.
HashMap<String, Integer> countenLetters = new HashMap<>();
//the next line generates a key-value-store whose key is the letter in the string
//and the value is the accumulated occurrence of said letter.
Arrays.asList(strs.split("")).stream().forEach((String letter) -> {
Integer count = 0;
try {
count = countenLetters.get(letter).intValue();
} catch (Exception e) {
//tried to access a non existing value in the map
//this happens if there is a letter which was not set in the map until now.
//i.e. the first time the letter is encountered.
//this is no error. could have done it with an if also.
}
countenLetters.put(letter, ++count);
});
//do with this stuff what you want;
countenLetters.forEach((k,v) -> {
System.out.println("Letter "+k+" occurs "+v+" times in the string.");
});
}
}

Related

Error on the for loop - trying to use loop to count the repetition of letter

On the for loop I have the Java applet is showing me that I have an error. I am trying to use the for loop to count the repetition of letter.
String countString = "";
for (int i = 0; i < 26; i++){
// at the line below, my java applet says I have an error, and that the
//"letterCounts" should be a int and not a string, but I need it to be a string
String n = letterCounts[i];
if (n.equals("0")) {
countString = countString + " ";
} else if (n.length() == 1) {
countString = countString + " " + n + " ";
} else {
countString = countString + n + " ";
}
}
this.countLabel.setText(countString);
You donot show the definition of letterCounts, but I bet it is int[] letterCounts.
So since letterCounts is an array of int, you cannot just assign it to a String.
Just change String n to int n and your comparison to n == 0 and it should work. See below:
String countString = "";
for (int i = 0; i < 26; i++)
{
int n = letterCounts[i];
if (n == 0) {
countString = countString + " ";
} else if (n < 10) {
countString = countString + " " + n + " ";
} else {
countString = countString + n + " ";
}
}
this.countLabel.setText(countString);

returning ArrayIndexOutOfBoundsException error for unknown reason

I am trying to create a basic bubble sort program but at some point the array tries to reference the 11th position despite the array being 10 long and i am not sure when it occurs
int Last, i = 0, Temp;
int[] Numbers = new int[10];
String[] NumbersString = new String[10];
String initialString = TextBox.getText();
NumbersString = initialString.split(" ");
while(i<10){
Numbers[i] = Integer.parseInt(NumbersString[i]);
i = i + 1;
}
Last = 9;
Boolean Swapped = true;
while(Swapped = true) {
Swapped = false;
i = 0;
while(i < Last) {
if(Numbers[i] > Numbers[i+1]){
Temp = Numbers[i];
Numbers[i] = Numbers[i+1];
Numbers[i+1] = Temp;
Swapped = true;
}
i = i + 1;
}
Last = Last-1;
}
String Result = Numbers[0] + " " + Numbers[1] + " " + Numbers[2] + " " + Numbers[3] + " " + Numbers[4] + " " + Numbers[5] + " " + Numbers[6] + " " + Numbers[7] + " " + Numbers[8] + " " + Numbers[9];
ResultText.setText(Result);
change
while(Swapped = true) {
to
while(Swapped == true) {
What is happening is that Last is firstly wrapping to Negative and then when it gets to the minimum negative number it wraps to Integer.MAX_VALUE and then i will exceed 9
just try to put the length of the Array in here.
int Last, i = 0, Temp;
int[] Numbers = new int[10];
String[] NumbersString = new String[10];
String initialString = "1";
NumbersString = initialString.split(" ");
while (i < NumbersString.length) { // <-- I change it to NumbersString.length
Numbers[i] = Integer.parseInt(NumbersString[i]);
i = i + 1;
}
Last = Numbers.length-1; // <-- I change it to Numbers.length-1
Boolean Swapped = true;
while (Swapped) { // <-- I change it to Swapped only because your Swapped is a Boolean type, no need to equals it into true.
Swapped = false;
i = 0;
while (i < Last) {
if (Numbers[i] > Numbers[i + 1]) {
Temp = Numbers[i];
Numbers[i] = Numbers[i + 1];
Numbers[i + 1] = Temp;
Swapped = true;
}
i = i + 1;
}
Last = Last - 1;
}
String Result = Numbers[0] + " " + Numbers[1] + " " + Numbers[2] + " " + Numbers[3] + " " + Numbers[4] + " "
+ Numbers[5] + " " + Numbers[6] + " " + Numbers[7] + " " + Numbers[8] + " " + Numbers[9];
System.out.println(Result);
}

'If' and 'Else' Not Working in Java? [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
I'm trying to create a simple binary to decimal converter for my CS class to get a little extra credit. We only use Java in my class, so I'm making it on the Java platform. I've set up a homepage to call my class methods from to make it easier for me when I have multiple classes for the lessons I learn in the CS class. I'm calling my first method, stringSplit, which takes the binary value given as the argument, converts it to a String, then uses .substring to slice it up into each bit. It sets each bit to a variable to be later analyzed. Next, it runs through my bi2decFunctions method. This is what I have here:
public static void bi2decFunctions(String num128, String num64, String num32, String num16, String num8, String num4, String num2, String num1){
int num128Return;
int num64Return;
int num32Return;
int num16Return;
int num8Return;
int num4Return;
int num2Return;
int num1Return;
System.out.println(" " + num128 + " " + num64 + " " + num32 + " " + num16 + " " + num8 + " " + num4 + " " + num2 + " " + num1);
//128
if(num128 == "1"){
num128Return = 128;
} else {
num128Return = 0;
}
//64
if(num64 == "1"){
num64Return = 64;
} else {
num64Return = 0;
}
//32
if(num32 == "1"){
num32Return = 32;
} else {
num32Return = 0;
}
//16
if(num16 == "1"){
num16Return = 16;
} else {
num16Return = 0;
}
//8
if(num8 == "1"){
num8Return = 8;
} else {
num8Return = 0;
}
//4
if(num4 == "1"){
num4Return = 4;
} else {
num4Return = 0;
}
//2
if(num2 == "1"){
num2Return = 2;
} else {
num2Return = 0;
}
//1
if(num1 == "1"){
num1Return = 1;
} else {
num1Return = 0;
}
System.out.println(" " + num128Return + " " + num64Return + " " + num32Return + " " + num16Return + " " + num8Return + " " + num4Return + " " + num2Return + " " + num1Return);
bi2decDisplay(num128, num64, num32, num16, num8, num4, num2, num1, num128Return, num64Return, num32Return, num16Return,
num8Return, num4Return, num2Return, num1Return);
}
Each time I run this, the correct values for my 8-bit input shows up, but the num(1-128) return variables all equal 0. The 'if' statements aren't even affecting the outcome of them. Anyone have any idea?
I'd also like to present this to my CS class, so I'd like a 1-10 scale on the neatness and quality of my code.
Do not compare strings with ==, say equals:
str1.equals(str2)

Project Euler 8

I've read some topics on the project Euler problem 8. However I don't know why my code is giving me the wrong answer.
package main;
import java.util.ArrayList;
public class Euler8 {
public static void main(String[] args) {
String bigNumber = "73167176531330624919225119674426574742355349194934"
+ "96983520312774506326239578318016984801869478851843"
+ "85861560789112949495459501737958331952853208805511"
+ "12540698747158523863050715693290963295227443043557"
+ "66896648950445244523161731856403098711121722383113"
+ "62229893423380308135336276614282806444486645238749"
+ "30358907296290491560440772390713810515859307960866"
+ "70172427121883998797908792274921901699720888093776"
+ "65727333001053367881220235421809751254540594752243"
+ "52584907711670556013604839586446706324415722155397"
+ "53697817977846174064955149290862569321978468622482"
+ "83972241375657056057490261407972968652414535100474"
+ "82166370484403199890008895243450658541227588666881"
+ "16427171479924442928230863465674813919123162824586"
+ "17866458359124566529476545682848912883142607690042"
+ "24219022671055626321111109370544217506941658960408"
+ "07198403850962455444362981230987879927244284909188"
+ "84580156166097919133875499200524063689912560717606"
+ "05886116467109405077541002256983155200055935729725"
+ "71636269561882670428252483600823257530420752963450"
;
ArrayList<Integer> myArray = new ArrayList<Integer>();
int counter = 1;
int current = 0;
int product = 1;
int maximumProduct = 0;
for(int i = 0; i < bigNumber.length(); i++) {
String b = "" + bigNumber.charAt(i);
current = Integer.parseInt(b);
myArray.add(current);
if(counter % 5 == 0) {
for(int x : myArray) {
product = x * product;
}
if(product > maximumProduct) {
maximumProduct = product;
}
myArray.clear();
product = 1;
}
counter++;
}
System.out.println(maximumProduct);
}
}
I'm getting the answer 31752 and the right one is 40824. Since this is for a homework I can't copy the solution to the problem so I would like any explanation on why my code is not working so I can fix it.
Thanks.
You were not considering the right elements to multiply. Each product is obtained by multiplying 5 consecutive digits, for each digit the code below saves these digits in myArray
public static void main(String[] args) {
String bigNumber = "73167176531330624919225119674426574742355349194934"
+ "96983520312774506326239578318016984801869478851843"
+ "85861560789112949495459501737958331952853208805511"
+ "12540698747158523863050715693290963295227443043557"
+ "66896648950445244523161731856403098711121722383113"
+ "62229893423380308135336276614282806444486645238749"
+ "30358907296290491560440772390713810515859307960866"
+ "70172427121883998797908792274921901699720888093776"
+ "65727333001053367881220235421809751254540594752243"
+ "52584907711670556013604839586446706324415722155397"
+ "53697817977846174064955149290862569321978468622482"
+ "83972241375657056057490261407972968652414535100474"
+ "82166370484403199890008895243450658541227588666881"
+ "16427171479924442928230863465674813919123162824586"
+ "17866458359124566529476545682848912883142607690042"
+ "24219022671055626321111109370544217506941658960408"
+ "07198403850962455444362981230987879927244284909188"
+ "84580156166097919133875499200524063689912560717606"
+ "05886116467109405077541002256983155200055935729725"
+ "71636269561882670428252483600823257530420752963450"
;
;
ArrayList<Integer> myArray = new ArrayList<Integer>();
int counter = 1;
int current = 0;
int product = 1;
int maximumProduct = 0;
for(int i = 0; i < bigNumber.length(); i++) {
String b = "" + bigNumber.charAt(i);
current = Integer.parseInt(b);
myArray.add(current);
counter++;
if(counter == 5) {
for(int x : myArray) {
product = x * product;
}
if(product > maximumProduct) {
maximumProduct = product;
}
myArray.remove(0);
product = 1;
}
counter=myArray.size();
}
System.out.println(maximumProduct);
}
}
See also Greatest product of five consecutive digits in a 1000-digit number

NoSuchElementException reading/ scanning input

Here is the main problem:
java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Unknown Source)
at ExamAnalysis.main(ExamAnalysis.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:271)
The program compiles and runs. It's just that I am either getting the java.util.NoSuchElementException along with my five jother errors with (answer.charAt(i) == char) near the bottom. Here is my program:
import java.io.*;
import java.util.Scanner;
class ExamAnalysis
{
public static void main(String [] args) throws FileNotFoundException
{
Scanner keyboard = new Scanner(System.in);
System.out.println("Please type the correct answers to the exam questions, one right after the other: ");
String answers = keyboard.nextLine();
System.out.println("Where is the file with all the student responses? ");
String responses = keyboard.nextLine();
Scanner read = new Scanner(new File(responses));
while (read.hasNextLine())
{
for (int i = 0; i <= 10; i++)
{
responses = read.nextLine();
int p = 1;
p += i;
System.out.println("Student " + p + " responses: " + responses.substring(0,10));
}
System.out.println("Thank you for the data on 9 students. Here's the analysis: ");
resultsByStudents(responses, answers);
analysis(responses);
}
}
public static void resultsByStudents(String responses, String answers)
{
System.out.println ("Student # Correct Incorrect Blank");
System.out.println ("~~~~~~~~~ ~~~~~~~ ~~~~~~~~~ ~~~~~");
int student = 0;
int correct = 0;
int incorrect = 0;
int blank = 0;
for (int i = 0; i <= 9; i++)
{
for (int j = 0; j <= responses.length(); j++)
{
if ((responses.charAt(j)) == answers.charAt(j))
correct++;
else if ((responses.charAt(j)) != answers.charAt(j))
incorrect++;
else
blank++;
}
System.out.println(student + " " + correct + " " + incorrect + " " + blank);
student++;
}
}
public static void analysis(String responses)
{
System.out.println("QUESTION ANALYSIS (* marks the correct response)");
System.out.println("~~~~~~~~~~~~~~~~~");
//stores the percentage of each choice chosen
double A = 0;
double B = 0;
double C = 0;
double D = 0;
double E = 0;
double X = 0;
// tallys every variable chosen per question
for (int i = 0; i <= 10; i++) // go through all the questions
{
for (int j = 0; j <= responses.charAt(i); j++) //go through all the student responses
{
// variable that are being tallied
int chooseA = 0;
int chooseB = 0;
int chooseC = 0;
int chooseD = 0;
int chooseE = 0;
int chooseBlank = 0;
//variables take percentage of choices that have been chosen from each student
A = chooseA/9;
B = chooseB/9;
C = chooseC/9;
D = chooseD/9;
E = chooseE/9;
X = chooseBlank/9;
// variables that will print the asterisk with certain character of correct answer
String a = "A";
String b = "B";
String c = "C";
String d = "D";
String e = "E";
String blank = "blank";
if (responses.charAt(j) == A)
chooseA++;
else if (responses.charAt(j) == B)
chooseB++;
else if (responses.charAt(j) == C)
chooseC++;
else if (responses.charAt(j) == D)
chooseD++;
else if (responses.charAt(j) == E)
chooseE++;
else
chooseBlank++;
System.out.println("Question #" + i);
if (answers.charAt(i) == 'A') a = "A*"; // answers cannot be resolved(I already made it a global variable in my main method.)
else if (answers.charAt(i) == 'B') b = "B*";// answers cannot be resolved
else if (answers.charAt(i) == 'C') c = "C*";// answers cannot be resolved
else if (answers.charAt(i) == 'D') d = "D*";// answers cannot be resolved
else if (answers.charAt(i) == 'E') e = "E*";// answers cannot be resolved
System.out.println(a + " " + b + " " + c + " " + d + " " + e + " " + blank);
System.out.println (chooseA + " " + chooseB + " " + chooseC + " " + chooseD + " " + chooseE + " " + chooseBlank );
System.out.println (A + " " + B + " " + C + " " + D + " " + E + " " + X);
}
}
}
}
while (read.hasNextLine())
{
for (int i = 0; i <= 10; i++)
{
responses = read.nextLine();
int p = 1;
p += i;
System.out.println("Student " + p + " responses: " + responses.substring(0,10));
}
System.out.println("Thank you for the data on 9 students. Here's the analysis: ");
resultsByStudents(responses, answers);
analysis(responses);
}
}
Your logic here is confusing you. read.nextLine(); "Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line."
So you are saying, does it have a line? If so, read the next 10...well...11 lines, which isn't what you want. You don't know if there are 11 lines past this point. Don't know what that text file looks like, but you will want to restructure this part to either say, "While it has a next line", or "Read 11 lines"
Remove the for loop may resolve the issue. You are checking only once by using while(hasNextLine() ) but calling read.nextLine() 10 times in for loop.
for (int i = 0; i <= 10; i++)
{
responses = read.nextLine();
.......
}
int i = 0;
int numberOfStudents = 9;
while (i < numberOfStudents && read.hasNextLine()){
responses = read.nextLine();
i++;
System.out.println("Student " + i + " responses: " + responses.substring(0,10));
}
System.out.println("Thank you for the data on "+ numberOfStudents +" students. Here's the analysis: ");
resultsByStudents(responses, answers);
analysis(responses);
i < numberOfStudents : makes the required number of inserts
read.hasNextLine() : checks if there is input from console. If not the program waits for input.
for (int i = 0; i <= 10; i++)
count from 0 -> 10 = 11 students

Categories