Loop through char array and count chars - java

I'm trying to optimize my Java code so I try things. In my search for a short way I produced the code here below. This throws an Exception. Can you tell me why? Can't I loop through a string by a char Array?
public class Input {
public static void main(String[] args) {
String check = "Dit moet toch gewoon te doen zijn !!";
check = check.toLowerCase();
int[] counter = {0, 0, 0, 0, 0};
char[] vowel = {'a', 'e', 'i', 'o', 'u'};
int total = 0;
for (int i = 0; i < check.length(); i++)
if (check.charAt(i) == vowel[i])
counter[i]++;
for (int t : counter)
total += t;
System.out.println("Aantal klinkers: \t" + total);
}
}

Your code reads like this:
For each character in "check"
if character at index in "check" is character at index in "vowel"
That's probably not what you're looking for. The exception you're getting is because there are only 5 characters in "vowel" but alot in "check" (i'm not counting)
Now, I'm assuming what you're wanting to do is actually count the number of each vowel in "check"
You should actually use a nested for loop in this case.
for (int i = 0; i < check.length(); i++) {
for (int v = 0; v < vowel.length; v++) {
if (check.charAt(i) == vowel[v]) {
counter[v]++;
break;
}
}
}

for (int i = 0; i < check.length(); i++)
if (check.charAt(i) == vowel[i])
counter[i]++;
This loop goes from 0 to check.length(); but your array vowel[] has 5 element. So it generate array out of bound exception.

One more for the clever regex department so you don't have to make your string lowercase and lose the cases for vowels:
if (check.matches("(?i)[^a-z][a-z].*"))
System.out.println("Vowels found: " + check.replaceAll("[^a-z]+", ""));

You must have two loops
One for going through each char in string and a for loop going through each vowel array like so
for (int i = 0; i < check.length(); i++)
for (int p = 0; p < vowel.length; p++)
if (check.charAt(i) == vowel[p])
counter[p]++;
Enjoy.

You could use a regex for this operation:
Pattern vowels = Pattern.compile("(?i)[aeiou]");
String check = "Dit moet toch gewoon te doen zijn !!";
Matcher matcher = vowels.matcher(check);
while(matcher.find()) {
System.out.println("found vowel: " + matcher.group());
}
Explanation of regex:
(?i) make pattern case insensitive, [aeiou] characters to match.

Related

Need a help figuring out some nested iteration things in Java

I'm pretty new to programming and just started not to long ago doing some CS, currently my assignment is to is to write a program that prints each letter of the alphabet and the number of times that letter occurs in the phrase. It needs to include:
-Loop to iterate through the alphabet (the outer loop)
-Loop to iterate through all the letters of a phrase (the inner loop)
-Counter variable to count the number of times a letter is in the phrase
-Print statement to display the frequencies
I'm a little behind on this and having a hard time finding time to put into doing this assignment and just need some guidance on how to complete this simply, without complex things like Arrays and stuff.
As I said I haven't had much time to work on this, but here is the general layout/my plan of what I think it should look like:
public class LetterFrequencies
{
public static void main(String[] args)
{
int counter = 0;
String letters = "abcdefghijklmnopqrstuvwxyz";
String phrase = "This is a phrase";
System.out.println("The following shows the letter frequencies for the phrase");
//for (int i = _; i < _; i++) ??
{
//Print out statement like :System.out.println(letters.substing());
}
//possible while loop or for loop?
}
}
Feel free to correct me and anyway necessary since I need all the knowledge I can get to improve in the near future, thanks!
Try this solution without using Arrays or List, maybe it will help you:
public static void main(String[] args) {
int counter = 0;
String letters = "abcdefghijklmnopqrstuvwxyz";
String phrase = "This is a phrase".toLowerCase();
for (int i = 0; i < letters.length(); i++) {
int count = 0;
char a = letters.charAt(i);
for (int j = 0; j < phrase.length(); j++) {
if (a == phrase.charAt(j)) {
count++;
}
}
System.out.println("The letter " + letters.charAt(i) + " " + count);
}
}
For each letter you will have how much time it's used in you phrase.
Result :
The letter a 2
The letter b 0
The letter c 0
The letter d 0
The letter e 1
The letter f 0
The letter g 0
The letter h 2
The letter i 2
The letter j 0
The letter k 0
The letter l 0
The letter m 0
The letter n 0
The letter o 0
The letter p 1
The letter q 0
The letter r 1
The letter s 3
The letter t 1
The letter u 0
The letter v 0
The letter w 0
The letter x 0
The letter y 0
The letter z 0
This is one way:
String lettersString = "abcdefghijqlmnñopqrstuvwxyz";
char[] letters = lettersString.toCharArray();
int[] counts = new int[letters.length];
Arrays.fill(counts, 0);
String textBoxValue = "This is the message";
for (int i = 0; i < textBoxValue.length(); i++) {
char currentLetter = textBoxValue.charAt(i);
for (int j = 0; j < letters.length; j++) {
char letter = letters[j];
if (currentLetter == letter ||
currentLetter == Character.toUpperCase(letter)){
counts[j]++;
}
}
}
for (int i = 0; i < letters.length; i++) {
//Print it your own way
String message = letters[i] + " : " + counts[i];
Log.d(TAG, message);
System.out.println(message);
}
Probably this would help, just try to do a frequency Map.
public static Map<Character, Integer> frequencies(String yourPrhase){
Map<Character, Integer> frequency = new HashMap<>();
for(final char c : str.toCharArray()){
frequency.compute(c, (k, v) -> v == null ? 1: v++);
}
return frequency;
}
Then you can just do what you need with the frequency Map, probably print it out.
Also can try this one a little bit more functional.
public static Map<String, Long> frequencies2(String yourPrhase){
return str.chars()
.mapToObj(c -> String.valueOf((char) c))
.collect(Collectors.groupingBy(String::valueOf, Collectors.counting()));
}

(Java) Counting letters in a sentence?

The following is my code:
char[] array = new char[26] ;
int index = 0 ;
int letter = 0 ;
int countA = 0 ;
String sentence = "Once upon a time..." ;
if(sentence.contains("."))
{
String sentenceNoSpace = sentence.replace(" ", "").toLowerCase() ;
String sentenceFinal = sentenceNoSpace.substring(0, sentenceNoSpace.indexOf(".")) ;
char[] count = new char[sentenceFinal.length()] ;
for (char c = 'a'; c <= 'z'; c++)
{
array[index++] = c ;
for(int i = 0; i < sentenceFinal.length(); i++)
{
if(sentenceFinal.charAt(i) == c)
count[letter++] = c ;
//if(sentenceFinal.charAt(i) == 'a')
//countA++ ;
}
}
String result = new String(count) ; // Convert to a string.
System.out.println("\n" + result) ;
System.out.println("\nTotal number of letters is " + result.length()) ;
System.out.println(countA) ;
}
else
{
System.out.println("You forgot a period. Try again.") ;
}
I am having trouble counting how many a's, b's, c's, etc. are in a given sentence. There is one way I can do it and it is this part
//if(sentenceFinal.charAt(i) == 'a')
//countA++ ;
which I can just create all the way to z. Is there a more efficient way?
Note: No using Hashmap or any other advance techniques.
There is no need of eliminating spaces. This is just additional work you're doing.
int countOfLetters = 0 ;
String sentence = "Once upon a time..." ;
sentence = sentence.toLowerCase();
int[] countOfAlphabets = new int[26];
for (int i = 0; i < sentence.length(); i++) {
if (sentence.charAt(i) >= 'a' && sentence.charAt(i) <= 'z') {
countOfAlphabets[sentence.charAt(i) - 97]++;
countOfLetters++;
}
}
So, countOfLetters will give you the total count of letters.
If you want individual count, suppose for example, you want count of 'c',
You can get it by accessing countOfAlphabets array like countOfAlphabets['c' - 97] (97 being the ASCII value of 'a')
Use an int array letterCounts that will store the counts for each letter. Assuming the case of the letters can be ignored, the length of the letterCounts array will be 26.
Iterate over the string's characters and update the corresponding integer in the array. Use its ASCII value to find the corresponding index, as follows.
letterCounts[c - 97]++
97 is the ASCII value of 'a', whose count needs to be stored at index 0.
In this way, subtracting 97 from the character's ASCII value will give the corresponding index for that character.
Note: This is assuming that you want to store the counts for lowercase letters.
Pretty fiddly without using maps, but this will count all characters in a string.
You might want to modify to exclude things like spaces etc.
public class Main {
public static void main(String[] args) {
String sentence = "Once upon a time...";
// Create an array of size 256 ASCII_SIZE
int count[] = new int[256];
int length = sentence.length();
// Initialize count array index
for (int i = 0; i < length; i++)
count[sentence.charAt(i)]++;
// Create an array of given String size
char chars[] = new char[sentence.length()];
for (int i = 0; i < length; i++) {
chars[i] = sentence.charAt(i);
int find = 0;
for (int j = 0; j <= i; j++) {
// If any matches found
if (sentence.charAt(i) == chars[j])
find++;
}
if (find == 1) {
System.out.println("Occurrence of " + sentence.charAt(i) + " is:" + count[sentence.charAt(i)]);
}
}
}
}
Which outputs:
Occurrence of O is:1
Occurrence of n is:2
Occurrence of c is:1
Occurrence of e is:2
Occurrence of is:3
Occurrence of u is:1
Occurrence of p is:1
Occurrence of o is:1
Occurrence of a is:1
Occurrence of t is:1
Occurrence of i is:1
Occurrence of m is:1
Occurrence of . is:3
Check Below code You can have a 26 length array and index will increment according to the presence of the alphabet.
public void getResult(){
int [] charCount = new int [26];
int countA = 0 ;
String sentence = "Once upon a time..." ;
if(sentence.contains("."))
{
String sentenceNoSpace = sentence.replace(" ", "").toLowerCase() ;
String sentenceFinal = sentenceNoSpace.substring(0, sentenceNoSpace.indexOf(".")) ;
char[] sentenceCharArray = sentenceFinal.toCharArray();
//char a = 97;
for (int i = 0; i <sentenceCharArray.length ; i++) {
int index = sentenceCharArray[i] - 97 ;
if(index >= 0 && index <= 26) {
charCount[index] += 1;
}
}
System.out.print("Result : ");
for (int i = 0; i < charCount.length ; i++) {
System.out.print(charCount [i]+" , ");
}
System.out.println("\nTotal number of letters is " + sentenceCharArray.length) ;
}
else
{
System.out.println("You forgot a period. Try again.") ;
}
}
Since there are 26 letters in the US alphabet, you can use an int[] with a size of 26
int[] letterCount = new int[26];
to hold the count of each letter where index 0 represents 'a', 1 represents 'b', etc...
As you traverse through the sentence, check if the character you're on is a letter, Character.isLetter(), then increment the element in the array that represents the letter.
letterCount[letter - 'a']++;
We subtract 'a' from the letter to give us the correct index.
Code Sample
package stackoverflow;
public class Question {
public static void main(String[] args) {
String sentence = "The quick brown fox jumps over the lazy dog.";
int[] letterCount = new int[26];
if (sentence.contains(".")) {
// toLowerCase() the sentence since we count upper and lowercase as the same
for (char letter : sentence.toLowerCase().toCharArray()) {
if (Character.isLetter(letter)) {
letterCount[letter - 'a']++;
}
}
// Display the count of each letter that was found
int sumOfLetters = 0;
for (int i = 0; i < letterCount.length; i++) {
int count = letterCount[i];
if (count > 0) {
System.out.println((char)(i + 'a') + " occurs " + count + " times");
sumOfLetters += count;
}
}
System.out.println("Total number of letters is " + sumOfLetters);
} else {
System.out.println("You forgot a period. Try again.");
}
}
}
Result
a occurs 1 times
b occurs 1 times
c occurs 1 times
d occurs 1 times
e occurs 3 times
f occurs 1 times
g occurs 1 times
h occurs 2 times
i occurs 1 times
j occurs 1 times
k occurs 1 times
l occurs 1 times
m occurs 1 times
n occurs 1 times
o occurs 4 times
p occurs 1 times
q occurs 1 times
r occurs 2 times
s occurs 1 times
t occurs 2 times
u occurs 2 times
v occurs 1 times
w occurs 1 times
x occurs 1 times
y occurs 1 times
z occurs 1 times
Total number of letters is 35
Rebuttal Question
What is wrong with using Java 8 and using the chars() of a String? With it, you can accomplish the same thing with less code. For the total number of letters, we just use String.replaceAll() and remove all non-letters from the String with the pattern [^A-Za-z]and use the length() of the result.
package stackoverflow;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Question {
public static void main(String[] args) {
String sentence = "The quick brown fox jumps over the lazy dog.";
System.out.println(sentence.toLowerCase().chars()
// Change the IntStream to a stream of Characters
.mapToObj(c -> (char)c)
// Filter out non lower case letters
.filter(c -> 'a' <= c && c <= 'z')
// Collect up the letters and count them
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting())));
System.out.println("Total letter count is " + sentence.replaceAll("[^A-Za-z]", "").length());
}
}
Result
{a=1, b=1, c=1, d=1, e=3, f=1, g=1, h=2, i=1, j=1, k=1, l=1, m=1, n=1, o=4, p=1, q=1, r=2, s=1, t=2, u=2, v=1, w=1, x=1, y=1, z=1}
Total letter count is 35
You can solve it with Regex If Regex wont be considered as High-tech 🙂
Idea is simple: Remove all letters and subtract output from original string length to get counter
String sentence = "Once upon a time...";
String noLetterString = sentence.replaceAll("[a-zA-Z]", "");
int counterLetter = sentence.length() - noLetterString.length();
System.out.println("counter:" + counterLetter);
By old school programming 🙂
Idea here is in reverse, appending only letters
String sentence = "Once upon a time...";
String lowerCase = sentence.toLowerCase(); // to avoid comparison to UpperCase letters
StringBuilder counterStr = new StringBuilder();
for (char l : lowerCase.toCharArray()) {
if (l >= 'a' && l <= 'z') {
counterStr.append(l);
}
}
System.out.println("counterStr:" + counterStr);
System.out.println("counter:" + counterStr.length());
Here is the Update Code :
int[] array = new int[26] ;
String sentence = "Once upon a time..." ;
if(sentence.contains("."))
{
String sentenceNoSpace = sentence.replace(" ", "").toLowerCase() ;
String sentenceFinal = sentenceNoSpace.substring(0, sentenceNoSpace.indexOf(".")) ;
for (char c : sentenceFinal.toCharArray())
{
System.out.println(c+" "+(c-97));
array[c-97] += 1;
}
// System.out.println("\n" + Arrays.toString(array)) ;
for(int i=0; i< array.length;i++) {
if(array[i] != 0) {
char c = (char)(i+97);
System.out.println(c+" occured "+ array[i]+" times");
}
}
}
else
{
System.out.println("You forgot a period. Try again.") ;
}

How can I reprint a string starting from the first character till the last?

Given a non-empty string str like "Code" print a string like "CCoCodCode". Where at each index in the string you have to reprint the string up to that index.
I know there is DEFINITELY something wrong with this code that I wrote because the answer should be CCoCodCode, but instead it's giving me the alphabet! I don't know how I should change it.
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String str = scan.next();
int x = str.length();
for(char i = str.charAt(0); i <= str.charAt(x-1); i++)
{
System.out.print(i);
}
}
The char datatype can be treated as a number; you can increment it and manipulate it as a number.
What you really want is successive substrings of str to be printed. Loop over an int that will represent the ending position of the substring to be printed.
for (int i = 0; i < str.length(); i++)
{
System.out.print(str.substring(0, i + 1));
}
The end index argument to substring is exclusive, which is why I added 1.
Let's say that str is "Code". We can perform some mental substitutions to see what happens to your loop.
str is "Code"
x is 4
str.charAt(0) is 'C'
str.charAt(x-1) is 'e'
Making these substitutions, your loop is:
for(char i = 'C'; i <= 'e'; i++)
{
System.out.print(i);
}
Does this help you see the problem? I would think you'd have a loop from 0 to 3, not from 'C' to 'e'...
Many ways to get it done, suppose we have the input from user stored in a string named "c"... then...
String c = "Code";
for (int i = 0; i < c.length(); i++) {
System.out.print(c.substring(0, i));
}
System.out.print(c);
And this will print the sequence you are looking for.
It is outputting the alphabet because you are printing the counter instead of the characters in the string!
As it is, the first iteration of the for loop will set i to the first character, print that, then the operation i++ will increment i by one. Wait, so if the first character is "C", so i = 'C', what is i++?
Well it turns out characters can be represented by numbers. For example, 'C' has a value of 67. So incrementing it makes it 68, which represents 'D'. So if you run the loop on "Code", it will increment your counter 4 times, giving "CDEF". If you run on "Codecodecode", that will make the loop run 12 times, giving "CDEFGHIJKLMN".
What you really want is to loop through the string by its index instead:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String str = scan.next();
int length = str.length();
for (int i = 0; i < length; i++) {
System.out.print(str.substring(0, i + 1));
}
}

Unsure how to implement for loop

Hello I am having trouble implementing this function
Function:
Decompress the String s. Character in the string is preceded by a number. The number tells you how many times to repeat the letter. return a new string.
"3d1v0m" becomes "dddv"
I realize my code is incorrect thus far. I am unsure on how to fix it.
My code thus far is :
int start = 0;
for(int j = 0; j < s.length(); j++){
if (s.isDigit(charAt(s.indexOf(j)) == true){
Integer.parseInt(s.substring(0, s.index(j))
Assuming the input is in correct format, the following can be a simple code using for loop. Of course this is not a stylish code and you may write more concise and functional style code using Commons Lang or Guava.
StringBuilder builder = new StringBuilder();
for (int i = 0; i < s.length(); i += 2) {
final int n = Character.getNumericValue(s.charAt(i));
for (int j = 0; j < n; j++) {
builder.append(s.charAt(i + 1));
}
}
System.out.println(builder.toString());
Here is a solution you may like to use that uses Regex:
String query = "3d1v0m";
StringBuilder result = new StringBuilder();
String[] digitsA = query.split("\\D+");
String[] letterA = query.split("[0-9]+");
for (int arrIndex = 0; arrIndex < digitsA.length; arrIndex++)
{
for (int count = 0; count < Integer.parseInt(digitsA[arrIndex]); count++)
{
result.append(letterA[arrIndex + 1]);
}
}
System.out.println(result);
Output
dddv
This solution is scalable to support more than 1 digit numbers and more than 1 letter patterns.
i.e.
Input
3vs1a10m
Output
vsvsvsammmmmmmmmm
Though Nami's answer is terse and good. I'm still adding my solution for variety, built as a static method, which does not use a nested For loop, instead, it uses a While loop. And, it requires that the input string has even number of characters and every odd positioned character in the compressed string is a number.
public static String decompress_string(String compressed_string)
{
String decompressed_string = "";
for(int i=0; i<compressed_string.length(); i = i+2) //Skip by 2 characters in the compressed string
{
if(compressed_string.substring(i, i+1).matches("\\d")) //Check for a number at odd positions
{
int reps = Integer.parseInt(compressed_string.substring(i, i+1)); //Take the first number
String character = compressed_string.substring(i+1, i+2); //Take the next character in sequence
int count = 1;
while(count<=reps)//check if at least one repetition is required
{
decompressed_string = decompressed_string + character; //append the character to end of string
count++;
};
}
else
{
//In case the first character of the code pair is not a number
//Or when the string has uneven number of characters
return("Incorrect compressed string!!");
}
}
return decompressed_string;
}

Java Function Analysis

Okay..I am a total Python guy and have very rarely worked with Java and its methods. The condition is that I have a got a Java function that I have to explain to my instructor and I have got no clue about how to do so..so if one of you can read this properly, kindly help me out in breaking it down and explaining it. Also, i need to find out any flaw in its operation (i.e. usage of loops, etc.) if there is any. Finally, what is the difference between 'string' and 'string[]' types?
public static void search(String findfrom, String[] thething){
if(thething.length > 5){
System.err.println("The thing is quite long");
}
else{
int[] rescount = new int[thething.length];
for(int i = 0; i < thething.length; i++){
String[] characs = findfrom.split("[ \"\'\t\n\b\f\r]", 0);
for(int j = 0; j < characs.length; j++){
if(characs[j].compareTo(thething[i]) == 0){
rescount[i]++;
}
}
}
for (int j = 0; j < thething.length; j++) {
System.out.println(thething[j] + ": " + rescount[j]);
}
}
}
1st para: findfrom is a string, it is supposed to be "[ \"\'\t\n\b\f\r]" (regex) delimited.
2nd para: thething is a String array, it contains max 5 strings,
the method will find how many times the Strings in 'thething' in findfrom. and print the result out.
e.g.
findfrom="hello'there'happy'birthday'"
thething={"there","birthday","hello","birthday"}
result would be:
there: 1
birthday: 2
hello: 1
birthday: 2
btw, the line
String[] characs = findfrom.split("[ \"\'\t\n\b\f\r]", 0);
may move out of the for-loop. since the findfrom is not changed, no need do split repeatly.
if(thething.length > 5){
System.err.println("The thing is quite long");
}
If the length of the String[] thething is greater than 5. Print an error..
If not do what is inside the following else block.
else{
int[] rescount = new int[thething.length];
Create a new array of ints with size equal to the length of the String[] thething
for(int i = 0; i < thething.length; i++)
For each index i the String[] thething.
String[] characs = findfrom.split("[ \"\'\t\n\b\f\r]", 0);
Create a new String[] called characs that splits the String findfrom into several parts based on the regular expression "[ \"\'\t\n\b\f\r]". The 0 means this pattern will be applied as many times as possible.
for(int j = 0; j < characs.length; j++){
Now for each index j in the String[] characs...
if(characs[j].compareTo(thething[i]) == 0){
Compare the String in the characs String[] at index j with String in thething String[] at index i.
If the two match i.e the compareTo method returns 0.
rescount[i]++;
Increments the int that is at index i in the int[] rescount.
for (int j = 0; j < thething.length; j++) {
System.out.println(thething[j] + ": " + rescount[j]);
}
Finally for each index j in the String[] thething print out the String at that index and the int at that index in the int[] rescount
And also a String is an array of characters, Eg String string = "word" and a String[] is an array Strings. For example String[] strings = new String[]{"word1", "word2",....}.
public class Test {
public static void main(String[] args) {
search(
"you like me but do you \"like like\" me",
new String[]{"you", "like", "me", "not"}
);
}
/**
* Given a string of words (each word separated by one or more of the
* following characters: tab, carriage return, newline, single quote, double
* quote, a form feed, or a word boundary) count the occurrence of each
* search term provided, with a 5 term limit.
*
* #param findfrom
* the string of words
* #param thething
* the search terms. 5 at most, or count will not be performed.
*/
public static void search(String findfrom, String[] thething) {
if (thething.length > 5) {
System.err.println("The thing is quite long");
}
else {
String[] characs = findfrom.split("[ \"\'\t\n\b\f\r]", 0);
int[] rescount = new int[thething.length];
for (int i = 0; i < thething.length; i++) {
for (int j = 0; j < characs.length; j++) {
if (characs[j].compareTo(thething[i]) == 0) {
rescount[i]++;
}
}
}
for (int j = 0; j < thething.length; j++) {
System.out.println(thething[j] + ": " + rescount[j]);
}
}
}
}
Output
you: 2
like: 3
me: 2
not: 0
The Python version of that code would be something like this:
import sys
import re
def search(findfrom, thething):
"""Take a string and a list of strings. Printout each of the strings
in the list and a count of how many times that string appeared in the
input string. The string comparison will be based on the input string being
divided up into tokens. The delimiter for each token will be either a whitespace
character, a single quote, or a double quote. """
if len(thething) > 5:
sys.stderr.write("The thing is quite long")
else:
rescount = [0] * len(thething)
for i in range(0,len(thething)):
characs = re.split("[ \"\'\t\n\b\f\r]", findfrom)
for j in range(0,len(characs)):
if characs[j] == thething[i]:
rescount[i] = rescount[i] + 1
for j in range(0,len(thething)):
print thething[j] + ": " + str(rescount[j])
string = 'you like me but do you "like like" me'
strings = ["you", "like", "me", "not"]
search(string,strings)
Outputs:
you: 2
like: 3
me: 2
not: 0

Categories