Chemical Equation parsing - java

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

Related

Im having a problem with finding the palindrome of a upper case and lower case version of a word

So, I'm meant to get two version of a word given by user input, a version with just the lower case letters and then a version with just the upper case letters. Im then meant to find out if both of the words are palindromes. For example if the word was 'HEllO', the words HEO and ll would be created and then the output "HEO is not a palindrome, ll is a palindrome" would be printed. Im pretty sure my code makes sense but it won't say if either version of the original word is a palindrome. The following is the code.
public class comp1
{
public static void main(String []args)
{
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
String lower = lowerCaseLetters(input);
String upper = upperCaseLetters(input);
palindromeUpper(upper);
palindromeLower(lower);
}
public static String lowerCaseLetters(String input)
{
char[] ar = new char[input.length()];
for(int i = 0; i < input.length(); i++)
{
if(Character.isLowerCase(input.charAt(i)))
{
ar[i] = input.charAt(i);
}
}
String lowercase = new String(ar);
return lowercase;
}
public static String upperCaseLetters(String input)
{
char[] ar = new char[input.length()];
for(int i = 0; i < input.length(); i++)
{
if(Character.isUpperCase(input.charAt(i)))
{
ar[i] = input.charAt(i);
}
}
String uppercase = new String(ar);
return uppercase;
}
public static void palindromeUpper(String sent)
{
String reverse = "";
for(int i = sent.length()-1; i >= 0; i--)
{
reverse += sent.charAt(i);
}
if(sent.equals(reverse))
{
System.out.println("Upper case " + sent + " is a palindrome");
}
else
{
System.out.println("Upper case " + sent + " is not a palindrome");
}
}
public static void palindromeLower(String sent)
{
String reverse = "";
for(int i = sent.length()-1; i >= 0; i--)
{
reverse += sent.charAt(i);
}
if(sent.equals(reverse))
{
System.out.println("Lower case " + sent + " is a palindrome");
}
else
{
System.out.println("Lower case " + sent + " is not a palindrome");
}
}
}```
arrays don't skip 'empty' values. In fact, there's no such thing as an empty slot; char[] ar = new char[input.length()]; gives you a char array with length slots, and each slot is filled with an actual character: The NUL character.
You then copy over all lowercase letters to their appropriate position, which means all non-lowercase letters still have the NUL character. You then turn this back into a string, which will be a string with lots of NUL characters, and those NUL characters will then prevent the rest of your code from working properly; ll is a palindrome, sure. but \0\0ll\0 is not.
You can't resize arrays, you need to create them at the right size. Thus, you have two options:
loop through the string twice. First time, you just count lowercase letters, that is all you do. Second time, you copy over the lowercase letters, and not to position i, but to a counter you maintain (the first l occurs at i=2, but needs to go into ar[0]. The second l occurs at i=3, and needs to go into ar[1]).
Don't use a char array; use a StringBuilder instead, which grows on demand. just .append any lowercase letters.
2 is probably easier, but involves the use of another class (java.lang.StringBuilder).
Note then that your palindromeLower and palindromeUpper methods are identical, other than the messaging.

Getting the program to count the total amount of a char input from a user through a text file

My example text:
This-File-Contains-184-Characters.
The-Most-Frequent-Letter-Is-"E".
The-File-Includes-2-Upper-Case-Occurences
And-22-Lower-Case-Occurences-Of-"E".
The-Total-Number-Of-Its-Occurences-Is-24.
The example letter I'm using is "e".
My code:
import java.io.*;
import java.util.Scanner;
public class Homework4a
{
public static void main(String[] args) throws IOException
{
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter name of the input file: ");
String fileName = keyboard.nextLine();
System.out.println("Enter letter: ");
char letter = keyboard.nextLine().charAt(0);
File file = new File(fileName);
Scanner scan = new Scanner(new FileReader(file));
try
{
char lowerCaseLetter = (new Character(letter)).toString().toLowerCase().charAt(0);
char upperCaseLetter = (new Character(letter)).toString().toUpperCase().charAt(0);
int lowerCounter=0;
int upperCounter = 0;
while(scan.hasNextLine())
{
String input = scan.nextLine();
for(int i=0; i<input.length(); i++)
{
if(input.charAt(i)== lowerCaseLetter)
{
lowerCounter++;
}
else if(input.charAt(i)== upperCaseLetter)
{
upperCounter++;
}
}
}
int totalLowerCounter = lowerCounter;
int totalUpperCounter = upperCounter;
int totalCounterSum = totalLowerCounter + totalUpperCounter;
System.out.println("The lower-case letter " + lowerCaseLetter + " occurs " + totalLowerCounter + " times");
System.out.println("The upper-case letter " + upperCaseLetter + " occurs " + totalUpperCounter + " times");
System.out.println("The total number of occurrences (\"" + lowerCaseLetter + "\" and \"" + upperCaseLetter +
"\") is " + (totalCounterSum));
}
finally
{
scan.close();
}
}
}
I'll give you some pointers. My best advice is to use divide & conquer:
Get the file name from user input (you already know about Scanner)
Read the text file (check out BufferedReader and FileReader)
Remember that a char is basically just an int, look up an ASCII table
You can therefore use an array (int[]) where the indices are the ASCII values, the values are the number of occurence
Go over the contents of the file, char by char, and add to the array accordingly
Basically, divide & conquer is all about splitting a task into its smallest problems, then tackle them individually. By breaking an assignment down in this way, even quite complex problems will come down to small problems that are easy to solve.
What's also nice is that once you've broke it down like that, you can go ahead and write a method for each of these sub-tasks. This way, you get a nicely organized code "for free".
I figured out the problem, I needed to have the println outside of the loop. This code can help you read a text file and find a specific character by changing the variable in the "if else" statement to the specific character you need to find in the text file. It then calculates how many lowercase and uppercase letter and the total of them both.
Here is the code that u can formulate to find a letter count from a text file.i have pushed an harcoded letter 'a' u can change it to dynamic also.
import java.io.*;
import java.util.Scanner;
public class CountTheNumberOfAs {
public static void main(String[] args)throws IOException
{
String fileName = "JavaIntro.txt";
String line = "";
Scanner scanner = new Scanner(new FileReader(fileName));
try {
while ( scanner.hasNextLine() ){
line = scanner.nextLine();
int counter = 0;
for( int i=0; i<line.length(); i++ ) {
if( line.charAt(i) == 'a' ) {
counter++;
}
}
System.out.println(counter);
}
}
finally {
scanner.close();
}}}

Using characters as a delimiter for StringTokenizer in Java

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

How to print out the number of capital letters in a string - java

So I have this program I need to write. I'm, supposed to get an input string from a user and then print out how many capital letters and how many lowercased letters are in the string. I've looked everywhere in the book that I have and I just can't seem to find anything about how to print out the uppercase and lowercase letters. I've been doing a lot of googling as well and I couldn't find anything useful.
Anyway here's my code:
import java.util.Scanner; //calls out the method to get input from user
public class Verk1 {
public static void main(String args[])
{
Scanner innslattur = new Scanner(System.in); //input gotten from user
System.out.println("Sláðu inn textabrot í há- og lágstöfum.");
System.out.println("Forritið mun þá segja þér hve margir stafir eru af hverri gerð.");
System.out.println("Textabrot: ");
//The printouts before tell the user to enter in a string, the program will then print out //how many upper- and lowercase letters there are.
String strengur = innslattur.nextLine();
String hastafir = "";
for (int i=0; i<hastafir.length();i++);
{
System.out.println("Í textabrotinu eru " + hastafir + " hástafir");
}
}
}
I know the code is faulty/doesn't work, but do any of you know how I get the number of uppercase- lowercase letters to print them out?
Thanks in advance!
Cheers
I haven't tested it but I would look to do something like this.
String text = "This IS My TEXT StrinG";
int upperCaseCounter = 0;
int lowerCaseCounter = 0;
for (int i=0; i<text.length(); i++)
{
if (Character.isUpperCase(text.charAt(i)))
{
upperCaseCounter++;
}
else if(Character.isLowerCase(text.charAt(i)))
{
lowerCaseCounter++;
}
}
System.out.println("Total Uppercase Characters: " + upperCaseCounter);
System.out.println("Total Lowercase Characters: " + lowerCaseCounter);
You can do their fairly easily if you convert the string to a char[] first. You can then use the isUpperCase(char c) for each character in the string. http://www.tutorialspoint.com/java/character_isuppercase.htm
For some strange reason your for loop is referring to an empty string you've just declared, rather than the string you just read in from the user. However, if you change that, inside your loop you can get at the individual characters in the string with strengur.charAt(i) and you can test whether a letter is capital with Character.isUpperCase(ch) and you can check for a lower case letter with Character.isLowerCase(ch).
public void printCapsAndLowercaseCounts(String s) {
int uppercase = 0;
int lowercase = 0;
if (s != null) {
String s1 = s.toUpperCase();
String s2 = s.toLowerCase();
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == s1.charAt(i) ^ s.charAt(i) == s2.charAt(i)) {
if (s.charAt(i) == s1.charAt(i)) uppercase++;
else lowercase++;
}
}
}
System.out.println(uppercase + " " + lowercase);
}
Seems like this would do the trick, assuming you're not doing it an excessive amount. Just use a temporary string, and get the difference between the two:
int capLetterCount = originalString.length() - originalString.replaceAll("[A-Z]", "").length();

How to count how many times a keyword appears in a tax in java?

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.

Categories