Letter frequency array, converting int to char - java

My code below prints out a letter frequency table (number of letter occurances in a string) that is inputted from a scanner class. I Have everything working correctly except the last bit. When executed, the table displays letters a-z and the number of occurrences except for the last method LargestLength() method. Since my array 'score' uses int[26], instead of using a-z it uses ints 0-25. (0=A, 1=B, etc.) As of now my LargestLength method only displays the number (instead of the letter) which comes up the most but does not count the number of occurrences.
For example, If my string were to be "Hello", l shows up most frequently so i would like it to display, "Most Frequent: l 2" but with my code it displays "Most Frequent: 11" (11 = L). How would I go about fixing this?
Profile Class.
public class LetterProfile {
int score[] = new int [26];
public void countChars (String s) {
s = s.toLowerCase();
char a = 'a';
for (int i = 0; i < s.length(); i++) {
int next = (int)s.charAt(i) - (int) a;
if ( next< 26 && next >= 0)
score[next]++;
}
}
public int largestLength() {
int largest = 0;
int largestindex = 0;
for(int a = 0; a<26; a++) {
if(score[a] > largest) {
largest = score[a];
largestindex = a ;
}
}
return (char) largestindex;
}
public void printResults() {
largestLength();
for (int i = 0; i < score.length; i++) {
System.out.println( (char)(i+97) + ": " + score[i]);
}
System.out.println(("Most Frequent") + (": ") + largestLength());
}
}
A bit of a confusing explanation but any help would be appreciated.

If my string were to be "Hello", l shows up most frequently so i would like it to display, "Most Frequent: l 2" but with my code it displays "Most Frequent: 11" (11 = L). How would I go about fixing this?
Simple: String.valueOf((char)(number + 'A'));

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 sum of repetitive items inside for loop

I have two arrays :
String[] matnr = new String[] { "16400", "56000", "56000", "50000", "16400" };
String[] lfimg = new String[] { "4.000", "5.000", "6.000", "9.000", "10.560" };
I want to find sum of lfimg items having same matnr value i.e. for matnr 16400 sum output will be 14.560, for 56000 output will be 11.000 and matnr 50000 sum output will be 9.000
below block is written by me :
public static void main(String[] args) {
String[] matnr = new String[] { "16400", "56000", "56000", "50000", "16400" };
String[] lfimg = new String[] { "4.000", "5.000", "6.000", "9.000", "10.56" };
int n = matnr.length;
int i, j, x;
int count = 0;
int count1 = 0;
double value = 0.0;
// calculate unique material count
for (i = 0; i < n; ++i)
System.out.println(i + 1 + "compartment material : " + matnr[i]);
for (i = 0; i < n; i++) {
for (j = 0; j < i; j++)
if (matnr[i] == matnr[j])
break;
if (i == j) {
count = count + 1;
}
}
System.out.println("final count >>" + count);
String materialArray[] = new String[count];
for (i = 0; i < n; i++) {
for (j = 0; j < i; j++)
if (matnr[i] == matnr[j])
break;
if (i == j) {
materialArray[count1] = matnr[i];
System.out.println("Material array xxxx >>" + materialArray[count1]);
System.out.println("count1 before >>" + count1);
count1 = count1 + 1;
System.out.println("count1 after >>" + count1);
}
}
System.out.println("matnr.length >>" + matnr.length);
System.out.println("materialArray.length >>" + materialArray.length);
for (i = 0; i < matnr.length; i++) {
System.out.println("111Value >>> " + matnr[i]);
}
for (j = 0; j < materialArray.length; j++) {
System.out.println("222Value >>> " + materialArray[j]);
}
System.out.println("---- ******* ------------ *********** -------- ********** ------");
for (i = 0; i < materialArray.length; i++) {
for (j = 0; j < matnr.length; j++) {
if (materialArray[i].contains(matnr[j])) {
value = value + Double.parseDouble(lfimg[j]);
System.out.println("Value1 >>> " + value);
}
}
}
}
But I'm not getting desired output. It is coming as :
Value1 >>> 4.0
Value1 >>> 14.56
Value1 >>> 19.560000000000002
Value1 >>> 25.560000000000002
Value1 >>> 34.56
Where as I want output as :
Value1 >>> 14.560
Value1 >>> 11.000
Value1 >>> 9.000
Can anybody please assist in this regard.
You do not reset the value variable in your final forloop, hence why you're getting ever increasing numbers in your print, ending in 34.56. You want one value for each materialArray entry, so immediately after for (i = 0; i < materialArray.length; i++) {, you'd want value = 0.
You're using materialArray[i].contains(matnr[j]) - that's asking if matnr[j] is a substring of materialArray[i]. It seems rather clear you wanted equals instead. Minor nit and doesn't break here, but a bug nonetheless.
Your printer tool will print every time an individual entry matches, and prints nothing after you're gone through the whole list, resulting in this weird output. Your intent, presumably, is to let the inner loop (for (int j = 0; j < matnr.length; j++)) complete, and THEN you want to print. Thus, your sysout statement needs to be shifted two lines down, after the closing bracket of the inner for loop. Combine that with resetting your value and...
Value1 >>> 14.56
Value1 >>> 11.0
Value1 >>> 9.0
NB: A second issue is rounding errors. You basically should never toString() or otherwise directly print a float or double value. If you do, you get wonky weirdness like 19.560000000000002.
If I ask you, using decimal notation, to write down the result of 'one third', you must round. You can't write an infinite processing of .3333333, right? Computers (specifically, doubles and floats) are no different, but computers count in binary, not decimal. So, the computer has to round a bit, and then 'render' the value it has in decimal, and this is where the weirdness comes from. The inaccuracies introduced by this rounding cannot be avoided (at least, not with doubles and floats), but usually the inaccuracies do not creep into the relevant significance of your numbers. The solution is therefore to ALWAYS guide the libraries when printing your numbers, by telling it how many digits you are expecting. So, make it:
System.out.printf("Value1 >>> %.4f\n", value);
The %.4f tells the printer to print with no more than 4 digits after the dot, and printf does not automatically newline, so the \n tells it to print that newline explicitly.
Finally, there's the matter of this code style. This can be done far simpler (and more efficiently) using java's built in tools, such as HashMap:
public static void main(String[] args) {
String[] matnr = new String[] { "16400", "56000", "56000", "50000", "16400" };
String[] lfimg = new String[] { "4.000", "5.000", "6.000", "9.000", "10.56" };
var values = new HashMap<String, Double>();
// load values into the map.
for (int i = 0; i < matnr.length; i++) {
double z = Double.parseDouble(lfimg[i]);
values.compute(matnr[i], (m, v) -> v == null ? z : v + z); // [1]
}
// print them to show it works
for (var e : values.entrySet()) {
System.out.printf("%s: %.4f\n", e.getKey(), e.getValue());
}
}
The key line is the line marked [1]: It says: To compute the value for the value at the current matnr entry, if there is no existing value yet (v would be null), it's just the corresponding entry from lfimg, and if there is an existing value, it is the sum of what we had, plus the corresponding entry from lfimg.

(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 to format a String with spaces based on a specified length?

Trying to create a method in Java formats the string by stretching the content (by putting appropriate number of whitespaces) of a buffer, based on the length. So, based on a particular length given, the first character of the string is in the first index and the last character is located at the actual last index itself.
public static String format(String sentence, int length) {
if (sentence.length() >= length) {
return sentence;
}
StringBuilder sb = new StringBuilder();
String[] words = sentence.split("\\s+");
int usedCharacters = 0;
for (String word : words) {
usedCharacters += word.length();
}
int emptyCharacters = length - usedCharacters;
int spaces = emptyCharacters / words.length - 1;
for (String word : words) {
sb.append(word);
for (int i = 0; i <= spaces; i++) {
sb.append(" ");
}
}
return sb.toString();
}
For this unit test, this works:
#Test
public void isCorrectLength() {
String value = StringUtils.format("brown clown", 20);
assert(value.length() == 20);
}
So, here, the maximum buffer size is: 20
Total number of used characters is: 10
Total number of unused characters is: 10
The end result (if you print the String) is:
brown clown
The "n" in clown is at index 20...
However, there is an edge case with the following test (which causes it to break):
#Test
public void isCorrectLengthWithLongerSentence() {
String value = StringUtils.format("Love programming Java using Eclipse!", 50);
assert(value.length() == 50);
}
Buffer size: 50
Total Used Characters: 25
Total Unused Characters: 25
Spaces: 3
Final Length: 48
The end result (if you print the String) is:
Love programming Java using Eclipse!
Why is the final index 48 instead of 50?
The exclamation point "!" after "Eclipse", should be at 50 instead of 48...
Am suspecting that its due to my spaces calculation being off.
Thanks for taking the time to read this.
For this test
#Test
public void isCorrectLength() {
String value = StringUtils.format("Went to the slope and snowboarded for hours., 103);
assert(value.length() == 103);
}
This happens because you are dividing:
int spaces = emptyCharacters / words.length - 1;
This results in (66 / 8) - 1) = 7.25, and then you have a for loop, which does not account for the extra .25 This means you will not fill the desired buffer length.
Also, since you declared it as int, you will not get the extra 0.25, so you should change it to double, and cast the others as double as well.
You then can count the words and check if the extra 0.25 multiplied by the counter reaches 1, you add a space, and reset the counter.
double spaces = (double)emptyCharacters / (double)words.length - 1.0;
double extraSpace = spaces % 1;
double counter = 0;
for (String word : words) {
counter++;
sb.append(word);
for (int i = 0; i <= spaces; i++) {
sb.append(" ");
}
if ((counter * extraSpace) >= 1) {
sb.append(" "); // This is the extra space.
counter = 0;
}
}
Something like this. The problem resides in that not all words can have the same number of spaces. Some will have more, some will have less, in order to accommodate for the static buffer length. This is also a special case, because the remainder is 0.25, and will produce exactly 2 spaces, You still need to accommodate for the remainder of the remainder. (In case it does not reach 1 and you still have one more word.)
The following code makes up for this.
double spaces = (double)emptyCharacters / (double)words.length - 1.0;
double extraSpace = spaces % 1;
double counter = 0;
int wordIndex = 0;
for (String word : words) {
counter++;
wordIndex++;
sb.append(word);
for (int i = 0; i <= spaces; i++) {
sb.append(" ");
}
if ((counter * extraSpace) >= 1) {
sb.append(" "); // This is the extra space.
counter = 0;
}
if ((wordIndex == words.length - 1) && (counter * extraSpace) > 0) {
sb.append(" "); // This accounts for remainder.
}
}
This is not, in any way, elegant, but it works, for the previous test, and for example, for this new one:
#Test
public void isCorrectLength() {
String value = StringUtils.format("We went to the giant slope and snowboarded for hours., 103);
assert(value.length() == 103);
}
Split the string into words, based on white space.
Find the number of total spaces needed to pad the words to the desired string length (total length of string - words length).
Find the number of "space blocks" to be placed between words (number of words - 1).
Build the "space blocks" by iteratively adding spaces to each space block until we run out of spaces (see step 2).
Re-assemble the sentence by placing word, space block, word, etc.
private static String formatString(String sentence, int length) {
// parse words by white space
String[] words = sentence.split("\s+");
// calc the char length of all words
int wordsLength = 0;
for (String w: words) {
wordsLength += w.length();
}
// find the number of space blocks and initialize them
int spacesLength = length - wordsLength;
String[] spaceBlocks = new String[words.length - 1];
Arrays.fill(spaceBlocks, "");
// distribute spaces as evenly as possible between space blocks
int spacesLeft = spacesLength;
int k = 0;
while (spacesLeft > 0) {
spaceBlocks[k++] += " ";
if (k == spaceBlocks.length) {
k = 0;
}
spacesLeft--;
}
// assemble the buffer: for each word, print the word, then a spaces block, and so on
StringBuilder b = new StringBuilder();
for (int i = 0; i < words.length; i++) {
b.append(words[i]);
if (i < spaceBlocks.length) {
b.append(spaceBlocks[i]);
}
}
return b.toString();
}
public static void main(String[] args) {
String s;
String t;
s = "Hello, spaces.";
t = formatString(s, 50);
System.out.println(String.format("\"%s\" (length=%d)", t, t.length()));
s = "Hello, spaces.";
t = formatString(s, 51);
System.out.println(String.format("\"%s\" (length=%d)", t, t.length()));
s = "Good day, spaces.";
t = formatString(s, 52);
System.out.println(String.format("\"%s\" (length=%d)", t, t.length()));
s = "The quick brown fox.";
t = formatString(s, 53);
System.out.println(String.format("\"%s\" (length=%d)", t, t.length()));
s = "Ask not what your country can do for you.";
t = formatString(s, 54);
System.out.println(String.format("\"%s\" (length=%d)", t, t.length()));
s = "Ask not what your country can do for you, Bob.";
t = formatString(s, 55);
System.out.println(String.format("\"%s\" (length=%d)", t, t.length()));
}
Output,
"Hello, spaces." (length=50)
"Hello, spaces." (length=51)
"Good day, spaces." (length=52)
"The quick brown fox." (length=53)
"Ask not what your country can do for you." (length=54)
"Ask not what your country can do for you, Bob." (length=55)
In the cases where the spaces don't result in all even-length space blocks, the code favors placing them in the earlier-occurring space blocks.
Note for clarity I did not code edge cases (one-word strings, zero-length output, null inputs, words don't fit in buffer, etc). That's left as an exercise for the reader.

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