I am writing a program that takes an input of a list of numbers separated by commas and summing the total of the numbers. For example, I have the string "10, 20, 30, 40, 50"
I want to extract each number, "10" "20" "30" "40" "50" separately from the string and finding the sum of the list of numbers.
I found a solution, however, I find my code a bit messy and when I go back and look at it, I'll have quite a few "WTF"'s in a minute.
So,
I was wondering if there was a better way to write the following line:
StringTokenizer inputTokenizer = new StringTokenizer(input, "- ,\\n\\r\\t\\b\\fabcdefghijklmnopqrstuvwxyz");
My goal is that I want the program to use every character that is a non number as a delimiter for StringTokenizer.
So for instance the string "11abc33" should split into "11" and "33".
Here is my source code of what I came up with
public static void main(String[] args) {
do {
//Prompts user to enter a series of numbers and stores it in the String "input"
String input = JOptionPane.showInputDialog("Enter a series of numbers separated by commas.");
//total stores the sum of each number entered
int total = 0;
if ((input != null)) //checks if the user didn't cancel or quit the program
{
//sets every alphabetical character in the input String to lowercase
input = input.toLowerCase();
//creates a StringTokenizer that uses commas and white spaces as delimiters
StringTokenizer inputTokenizer = new StringTokenizer(input, "- ,\\n\\r\\t\\b\\fabcdefghijklmnopqrstuvwxyz");
//sums the total of each number entry
while (inputTokenizer.hasMoreTokens()) {
total = total + Integer.parseInt(inputTokenizer.nextToken());
}
} else {
//exit the program because the user hit cancel or exit
System.exit(0);
}
//display the sum of the total number entries
JOptionPane.showMessageDialog(null, "Total: " + total);
} while (true);
}
note that stringtokenizer separates numbers and substrings using spaces in normal mode. i mean using this constructor StringTokenizer(string)
but you can use another constructor to separate numbers using strTokenizer
StringTokenizer(String str, String delim)
which you can use "," as delim parameter and all substrings will be separated according to "," ,lock at this example:
String numbers = "10,20,30,40,50,60,70";
StringTokenizer t = new StringTokenizer(numbers, ",");
int sum=0;
while (t.hasMoreTokens()) {
sum+=Integer.parseInt(t.nextToken());
}
System.out.println("sum: " + sum);
you can also do it simply using split(String regex) method in String class
here is an example and solution for you.
String numbers = "10,20,30,40,50,60,70";// all numbers
String[] separated_numbers = numbers.split(",");// separate them by comma
// calculating sum
int sum = 0;
for (String number : separated_numbers) {
sum += Integer.parseInt(number);
}
// print sum
System.out.println("sum: " + sum);
There is no StringTokenizer constructor or factory method that does what you want any more simply. If you must have a StringTokenizer then I don't think there's a better way to get one, except inasmuch as you can tweak the characters in the delimiter string.
You wrote
My goal is that I want the program to use every character that is a non number as a delimiter for StringTokenizer.
but that seems a bit narrow-minded. It seems the most important thing would be the tokens, not the tokenizer, and if that's indeed the case for you then the regex-based String.split() might offer a satisfactory alternative:
for (String token : input.split("[^0-9]+")) {
int i = Integer.parseInt(token);
// ...
}
That takes you literally at your word, that you want to consider everything that is non-number as delimiter.
There are other regex-based solutions as well, such as using a pattern that matches one number to iterate through the string via Matcher.find().
You can do this using regex
do {
String input = JOptionPane.showInputDialog("Enter a series of numbers separated by commas.");
int total = 0;
if ((input != null))
{
Matcher m = Pattern.compile("(-?[0-9]+.[0-9]*)+").matcher(input);
// when using regex, the first group is always the full text, so we skip it.
for (int i = 1; i<=matcher.groupCount(); i++) {
total = total + Integer.parseInt(matcher.group(i));
}
} else {
System.exit(0);
}
JOptionPane.showMessageDialog(null, "Total: " + total);
} while (true);
You could replace all non number characters into one single character, then using split method to get a all numbers array.
public static void main(String[] args) {
do {
//Prompts user to enter a series of numbers and stores it in the String "input"
String input = JOptionPane.showInputDialog("Enter a series of numbers separated by commas.");
//total stores the sum of each number entered
int total = 0;
if ((input != null)) //checks if the user didn't cancel or quit the program
{
String[] characterTokens = input.split("[^0-9]+");
for (String characterToken : characterTokens) {
input.replace(characterToken, ",");
}
String[] numberTokens = input.split(",");
for (String numberToken: numberTokens) {
total += Integer.parseInt(numberToken);
}
} else {
//exit the program because the user hit cancel or exit
System.exit(0);
}
//display the sum of the total number entries
JOptionPane.showMessageDialog(null, "Total: " + total);
} while (true);
}
Related
I'm trying to figure out if I can count the characters of each token and display that information such as:
day is tokenized and my output would be: "Day has 3 characters." and continue to do that for each token.
My last loop to print out the # of characters in each token never prints:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<String> tokenizedInput = new ArrayList<>();
String sentenceRetrieved;
// getting the sentence from the user
System.out.println("Please type a sentence containing at least 4 words, with a maximum of 8 words: ");
sentenceRetrieved = sc.nextLine();
StringTokenizer strTokenizer = new StringTokenizer(sentenceRetrieved);
// checking to ensure the string has 4-8 words
while (strTokenizer.hasMoreTokens()) {
if (strTokenizer.countTokens() > 8) {
System.out.println("Please re-enter a sentence with at least 4 words, and a maximum of 8");
break;
} else {
while (strTokenizer.hasMoreTokens()) {
tokenizedInput.add(strTokenizer.nextToken());
}
System.out.println("Thank you.");
break;
}
}
// printing out the sentence
System.out.println("You entered: ");
System.out.println(sentenceRetrieved);
// print out each word given
System.out.println("Each word in your sentence is: " + tokenizedInput);
// count the characters in each word
// doesn't seem to run
int totalLength = 0;
while (strTokenizer.hasMoreTokens()) {
String token;
token = sentenceRetrieved;
token = strTokenizer.nextToken();
totalLength += token.length();
System.out.println("Word: " + token + " Length:" + token.length());
}
}
}
Example of Console:
Please type a sentence containing at least 4 words, with a maximum of 8 words:
Hello there this is a test
Thank you.
You entered:
Hello there this is a test
Each word in your sentence is: [Hello, there, this, is, a, test]
First off, I have added the necessary imports and built a class around this main method. This should compile.
import java.util.ArrayList;
import java.util.Scanner;
import java.util.StringTokenizer;
public class SOQ_20200913_1
{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<String> tokenizedInput = new ArrayList<>();
String sentenceRetrieved;
// getting the sentence from the user
System.out.println("Please type a sentence containing at least 4 words, with a maximum of 8 words: ");
sentenceRetrieved = sc.nextLine();
StringTokenizer strTokenizer = new StringTokenizer(sentenceRetrieved);
// checking to ensure the string has 4-8 words
while (strTokenizer.hasMoreTokens()) {
if (strTokenizer.countTokens() > 8) {
System.out.println("Please re-enter a sentence with at least 4 words, and a maximum of 8");
break;
} else {
while (strTokenizer.hasMoreTokens()) {
tokenizedInput.add(strTokenizer.nextToken());
}
System.out.println("Thank you.");
break;
}
}
// printing out the sentence
System.out.println("You entered: ");
System.out.println(sentenceRetrieved);
// print out each word given
System.out.println("Each word in your sentence is: " + tokenizedInput);
// count the characters in each word
// doesn't seem to run
int totalLength = 0;
while (strTokenizer.hasMoreTokens()) {
String token;
token = sentenceRetrieved;
token = strTokenizer.nextToken();
totalLength += token.length();
System.out.println("Word: " + token + " Length:" + token.length());
}
}
}
Next, let's look at this working example. It seems like everything up until your final while loop (the one that counts character length) works just fine. But if you notice, the while loop before the final one will continue looping until it has no more tokens to fetch. So, after it has finished gathering all of the tokens and has no more tokens to gather, you try and create the final while loop, asking it to gather more tokens. It would not have reached the while loop until it ran out of tokens to gather!
Finally, in order to solve this, you can simply go through the list that you added to in the second to last while loop, and simply cycle through that for your final loop!
For example:
int totalLength = 0;
for (String each : tokenizedInput) {
totalLength += each.length();
System.out.println("Word: " + each + " Length:" + each.length());
}
I am practising with algorithms, and I have this problem where I have to state how many of each of the letters in the word appear. e.g. input = floor , output = f1l1o2r1. I have the following code:
public static void main(String[] args) {// TODO code application logic here
Scanner inword = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
System.out.println("Enter word");
String word = inword.nextLine();
int length = word.length();
char[] wordArray = word.toCharArray();
for(int i = 0; i<length; i++){
int count = StringUtils.countMatches(word, String.valueOf(wordArray[i]));
System.out.print(wordArray[i] + count);
}
}
but instead I get this as output: 103109113113115 , when I enter floor as input
Your problem is that you print out the ascii-code value of the char. Try
System.out.print(wordArray[i]+"" + count);
instead of
System.out.print(wordArray[i] + count);
First, you should use countMatches(word, wordArray[i]); But that will not solve the entire problem. For example, your approach would lead to an output of "f1l1o2o2r1", and for the word "boohoo", you would get "b1o4o4h1o4o4".
You need to rethink how to do it if you want the output to show the number of consecutive same letters ("b1o2h1o2"), or if you want the number of each letter, specified only once, in order of first appearance ("b1o4h1"), or the number of appearances of letters alphabetically ("b1h1o4").
Considering the implementation of StringUtils.countMatches() is correct, the problem lies in the line
System.out.print(wordArray[i] + count);
Here, when you do wordArray[i], it returns a char. However, doing +count, converts that char into its ASCII value, and adds up count to it.
To fix it, try doing:-
System.out.print(wordArray[i] + " " + count);
I have to write a program that takes a user's chemical equation as an input, like NaCl2, and separate it out into individual elements and the number associated with them. Is there a way to parse through a string and pair the individual elements, like in NaCl2 into Na and Cl2?
As you mentioned in a comment, checking whether letters are uppercase or lowercase is key to this problem. What you're looking for to solve this is the Character.isUppercase() method. Your code should iterate over the characters in the input String and pass each to this method. I wrote up this rough draft of a code to demonstrate it (and it also prints the output for you - how convenient!):
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<String> elements = new ArrayList<>();
System.out.print("Enter formula: ");
String formula = sc.next();
String s = "";
for (int i=0; i<formula.length(); i++) {
if (Character.isUpperCase(formula.charAt(i))) {
if (!s.isEmpty()) {
elements.add(s);
}
s = "" + formula.charAt(i);
} else {
s += formula.charAt(i);
}
}
elements.add(s);
for (int i=0; i<elements.size(); i++) {
System.out.print(elements.get(i) + " ");
}
System.out.println();
}
This can be done a number of ways. One of them is using regular expressions. In this case the expression looks for an uppercase character, followed optionally by a lower case character, followed optionally by a number.
Pattern elementPattern = Pattern.compile("(\\p{Upper}\\p{Lower}?)(\\p{Digit}*)");
This can be used to find all the elements in the input:
Matcher elementMatcher = elementPattern.match(input);
while (elementMatcher.find()) {
String element = elementMatcher.group(1);
String count = elementMatcher.group(2);
System.out.println("Element: " + element + " count: " + count);
}
I am a very new to Java, so my knowledge is very limited. I have been trying to find the problem in this block of code.
import java.util.Scanner;
public class avgFinder {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Input numbers to average. Separate by a space.");
String nums = scan.next();
String[] parseNums = nums.split("[ ]");
double sum = 0;
int cnt = 0;
for (int a=0; a<=parseNums.length-1; a++) {
sum += Double.parseDouble(parseNums[a]);
cnt++;
}
double mean = sum/cnt;
System.out.println("Mean: " + mean);
}
}
But when I input a a set of numbers, only the first number gets printed instead of the actual mean. Example:
Input numbers to average. Separate by a space.
1 2 3
Mean: 1.0
Another thing is if I replace nums.split("[ ]") with nums.split("[,]") and put commas instead of spaces between the numbers in the output, it actually outputs the mean. I like spaces better though, it looks cleaner. Why is this happening?
Try this
use nextLine() instead of next()
nextLine returns complete line of text while next returns only one word
Also use nums.split(" ");
import java.util.Scanner;
public class avgFinder {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Input numbers to average. Separate by a space.");
String nums = scan.nextLine();
String[] parseNums = nums.split(" ");
double sum = 0;
int cnt = 0;
for (int a=0; a<=parseNums.length-1; a++) {
sum += Double.parseDouble(parseNums[a]);
cnt++;
}
double mean = sum/cnt;
System.out.println("Mean: " + mean);
}
}
Calling Scanner.next() will return the next element in a line before a space, so you only getting the first number in your input. Use Scanner.nextLine() which will return all the values on that line.
Scanner.next() returns the next word. By default, words are separated by whitespace. So when you call Scanner.next(), your scanner reads the digits of the first number, hits a space, and says "ok, that's the end of the word. Time to return the result" and you end up with just the first number.
That's why it works when you replace the spaces with commas: Without any spaces, the scanner doesn't find whitespace until it reaches the line break, so it returns the whole line.
Scanner.nextLine() returns the entire line instead of just one word (it reads until it hits a line break), so I'd suggest using that instead.
Question 1:
I am trying to count the frequency of a keyword, my code works except that it also counts
those words that also contain the keyword (for example, if I search "count", words like "account" will also be counted in.) Does someone know how to solve this?
Question 2:
I also wanna count the the number of unique words in a text (which means I count repeated word only once). I don't know how to achieve this either. My code only gives me the number of total words.
Here is my code:
import java.util.Scanner;
public class Text_minining {
/**
* #param args
*/
public static void main(String[] args) {
//Prompt the user for the search word
System.out.print("enter a search word: ");
//Get the user's search word input
Scanner keywordScanner = new Scanner(System.in);
String keyword = keywordScanner.nextLine();
keyword = keyword.toLowerCase();
//Prompt the user for the text
System.out.println("Enter a string of words (words separated by single spaces or tabs): ");
//Get the user's string input
Scanner userInputScanner = new Scanner(System.in);
String userInput = userInputScanner.nextLine();
userInput = userInput.toLowerCase();
int keywordCount = 0, wordCount = 0;
int lastIndex = 0;
while(lastIndex != -1){
lastIndex = userInput.indexOf(keyword,lastIndex);
if(lastIndex != -1){
keywordCount ++;
lastIndex = keyword.length() + lastIndex;
}
}
boolean wasSpace=true;
for (int i = 0; i < userInput.length(); i++)
{
if (userInput.charAt(i) == ' ') {
wasSpace=true;
}
else{
if(wasSpace == true) wordCount++;
wasSpace = false;
}
}
//Print the results to the screen
System.out.println("-------");
System.out.println("Good, \"" + keyword + "\"appears in the text and the word count is " + keywordCount);
System.out.println("The total number of unique words in the text is " + wordCount);
System.exit(0);
}
}
First: userInput.split(keyword).length - 1 will do the trick. Our use regex.
Second:
Set<String> uniqueWords = new HashSet<String>();
for (String word : userInput.split(" ")) {
uniqueWords.add(word);
}
System.out.println("Unique words count " + uniqueWords.size());
Just use string method split.
String words[] = userInput.split(keyword);
and then check and count the keyword...
for ( String w : words) {
// do check
}
Agree. Use split to create the array and then you can use
(new HashSet(Arrays.asList(yourArray))).size();
to find the count
I would suggest you this approach:
Split userInput string by white spaces: userInput.split("\\s+"). You will get an array. See String.split()
For question 1: iterate over the array comparing each string with your keyword. See String.equals() and String.equalsIgnoreCase().
For question 2: add the array to a Set. As this can't contain any duplicate item, its size will give you the answer.