Java String Manipulation: extracting integer and float from string based on pattern - java

I have the following two possible contents of a String.
Obviously the amounts always vary and I would like to extract the key information and
Case 0: pricesString = ""
Case 1: pricesString = "$0.023"
Case 2: pricesString = "10+: $1.46 100+: $0.16 500+: $0.04"
In Case 0 I would like to do nothing.
In Case 1 I would like to perform:
article.addPrice(1, 0.023);
In Case 2 I would like to perform:
article.addPrice(10, 1.46);
article.addPrice(100, 0.16);
article.addPrice(500, 0.04);
How can I extract this information so I can can call article.addPrice with the float and integer values contained?

That looks like a job for regex:
String pricesString = "10+: $1.46 100+: $0.16 500+: $0.04";
Pattern p = Pattern.compile("(\\d+)\\+: \\$(\\d\\.\\d\\d)");
Matcher m = p.matcher(pricesString);
while (m.find()) {
Intger.parseInt(m.group(1));
Double.parseDouble(m.group(2));
}
You can choose between the 3 cases by a simple .length() check. The code above is for the last case. The rest is eaiser

Apply the regex \d+\.?\d* as often as you can. The array of the results can be checked whether it contains 0, 1 or more values.
If there are 0, it is Case 0.
If there is one, it is Case 1. You can edd it with qunantity 1 to the articles.
If there are more, you can loop with something like
for(int i = 0; i < result.length / 2; i++) {
articles.addArticle(Integer.parseInt(result[i]), Double.parseDouble(result[i+1]));
}

Related

Complex numbers string/array in java?

I want to assign complex numbers to binary values which i am doing using complex class, easily available; but when a i am appending complex numbers to string buffer, returning into a string, one complex number is taking multiple entries. How can i place 1 number to 1 entry and read afterwards? Ending string data like this "2.0+2.0i2.0-2.0i2.0+2.0i2.0-2.0i-2.0+2.0i2.0+2.0i....". Now character at 0 is '2', char at 1 is '.' and so on.. I need char at 0 to be 2.0+2.0i. and afterwards i should be able to separate real and imaginary parts of each entry.
StringBuilder symbs = new StringBuilder();
Complex s1 = new Complex(-2,-2);
Complex s2 = new Complex(+2,-2);
Complex s3 = new Complex(+2,+2);
Complex s4 = new Complex(-2,+2);
/////////////////////Symbols to vector ////////////////////
for(int i=0; i< plo.length()-1; i+=2)
{
if(plo.charAt(i)=='1' && plo.charAt(i+1)=='0')
{
symbs.append(s1);
}
else if(plo.charAt(i)=='0' && plo.charAt(i+1)=='1')
{
symbs.append(s2);
}
else if(plo.charAt(i)=='0' || plo.charAt(i+1)=='0')
{
symbs.append(s3);
}
else if(plo.charAt(i)=='1' && plo.charAt(i+1)=='1')
{
symbs.append(s4);
}
}
printComplex(symbs.toString());
"I need char at 0 to be 2.0+2.0i." thats not possible, as a char is one character.
you can append semicolons after every complex and then split for them
Use Regex pattern matching similar like this [[0-9].0+[0-9].0i]+
Pass the string to the Matcher compiler and check available pattern is found on the given string. Based on that extract the value with programmatic logic to get real and imaginary parts.
Explanation on regex string
Real part
[0-9] --> it check value from 0 to 9 followed by . and followed by 0
Imaginary part
[0-9] --> it check value from 0 to 9 followed by . and followed by 0 and then by i

Simple math-to-english calculator

I'm currently taking a basic programming course. The teacher refuses to look at my code and attempts to guess the question I'm asking, and then answer that (incorrect) question. The basics of this is, it's supposed to take an equation, like 5 * 6, and output "Five times six equals 30," with the answer just being a number. The code I have right now is as such:
package mainPackage;
import java.util.*;
public class Main
{
public static void main(String[]args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Please enter the equation");
String input = scan.nextLine();
String space = " ";
int firstSpace = 0;
int secondSpace = 0;
int numInt1 = 0;
int numInt2 = 0;
String a = "0";
char b = 'a';
String c = "0";
firstSpace = input.indexOf(space);
String sub = input.substring((firstSpace + 1), input.length());
secondSpace = sub.indexOf(space);
a = input.substring(firstSpace--);
b = input.charAt(firstSpace++);
c = input.substring(secondSpace++);
numInt1 = Integer.parseInt(a);
numInt2 = Integer.parseInt(c);
String num1 = "";
String op = "";
String num2 = "";
switch (numInt1)
{
case 0:
{
num1 = "Zero";
}
case 1:
{
num1 = "One";
}
case 2:
{
num1 = "Two";
}
case 3:
{
num1 = "Three";
}
case 4:
{
num1 = "Four";
}
case 5:
{
num1 = "Five";
}
case 6:
{
num1 = "Six";
}
case 7:
{
num1 = "Seven";
}
case 8:
{
num1 = "Eight";
}
case 9:
{
num1 = "Nine";
}
}
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
She has told us that between each number and operand, she WILL put a space. So rather than 5/6, it would be 5 / 6, and that we only have to do it for 0 to 9, but still have to detect if she puts a two digit number, and print invalid number. This part I know how to do. The problem arises when I try to run this. No errors are showing up in the lines, but when I run it, I get this:
Exception in thread "main" java.lang.NumberFormatException: For input string: " * 6"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at mainPackage.Main.main(Main.java:44)
This ends up being this line:
numInt1 = Integer.parseInt(a);
When removing them, the code prints out something like this:
"5
* 6
* 6"
Would anyone know why this is happening? I feel as though it is something painfully obvious that I missed.
EDIT: Thank you all so much for your quick replies. She never taught us the split method. Thanks again!
First I think you should get familiar with the debugger. It's very useful and there is almost no way one can code a program larger than 20 lines without the need of it ;)
Now take into consideration two things here: substring(beginIndex) returns a sub-string beginning from that index (0 based) to the end of the string.
This is why "5 * 6".substring(1) will return " * 6" (1 is the "position"/index of the first space in the string "5 * 6", because it's 0-based).
That is why you are getting an Exception parsing the expression into an Integer value.
The other thing is, that firstSpace++ or firstSpace-- will increase and decrease the value of firstSpace, respectively, and will do it AFTER the rest of the command.
So actually:
a = input.substring(firstSpace--);
b = input.charAt(firstSpace++);
c = input.substring(secondSpace++);
is equivalent to something like that:
a = input.substring(firstSpace);
firstSpace = firstSpace - 1;
b = input.charAt(firstSpace);
firstSpace = firstSpace + 1;
c = input.substring(firstSpace);
firstSpace = firstSpace - 1;
And you lost what you wanted to achieve.
There are several solutions to your problems. Some of them are suggested above. Some use tools that are a bit more advanced, but you can also solve the problems without other help methods (longer and uglier, but will still work).
My advice is get used to using the debugger, it could help you find out the problem very quickly in this situation.
This can be done using String.split(String regex) function
String arr[] = input.split("\\s+");// splitting input by space
numInt1 = Integer.parseInt(arr[0]);//5
numInt2 = Integer.parseInt(arr[2]);//6
char b = arr[1].charAt(0);//*
If you know that the input is a number, a space, an operator, a space and a number, then that means the length of the input is five characters. Anything other than that is wrong. You can then also check whether these five characters match the given format.
In general, you should always verify user input before passing it to methods that expect a certain input. The user could enter anything and it's up to your program to ensure the input adheres to the desired format.
Your problem is most likely in these lines.
a = input.substring(firstSpace--);
b = input.charAt(firstSpace++);
There are two problems that I see. First the use of -- and ++ is actually changing the value of firstSpace. It looks like b will contain the space instead of the arithmetic operator. You can help yourself figure out what is going on by sprinkling some System.out.println() messages in there to see what is happening to your index variables.
Second, the substring method with a single parameter creates a substring from the given index to the end of the string. I think you may really want to do something like:
a = input.substring(0, firstSpace-1);
This will give you the substring from the beginning of input to the character before the first space.

Letters having the same equivalence

Looking ideas on how to go about accomplishing this. Basically I want certain characters to have equivalence.
For example: M = N
So: Mum = Nun
However: Mum can also equal Num.
I was advised to try a map of replacements and this worked until the third example where not all M's are to be changed to N's.
Thanks
This is the code for the map of replacements:
HashMap<String,String> replacements = new HashMap<>();
replacements.put("n","m");
replacements.put("m","n");
String ignoreFirstChar = names[j].charAt(0) + (names[j].substring(1,names[j].length()).replaceAll("[^a-zA-Z]+", "").toLowerCase());
String result = "";
for(int i1 = 0; i1 < ignoreFirstChar.length(); i1++) {
String rpl = replacements.get(ignoreFirstChar.charAt(i1)+"");
result += rpl==null?ignoreFirstChar.charAt(i1):rpl;
}
System.out.println(ignoreFirstChar);
System.out.println(result);
I assume M and m are not equivalent. Therefore, if M = N, we cannot say M = n. If you would like to use a "map of replacements" as you have been suggested, I would use it for the purpose of normalizing your strings.
You would take the current problem of
Given strings x and y, determine whether x equals y
and change it to
Given strings x and y, determine whether normalize(x) equals normalize(y)
The purpose of normalizing your strings is to apply any equivalence rules that you have, such as M = N. That way "Mum" would be converted to "Num", and then you can compare the two strings without having to worry about the rules because they've already been applied.
The normalize method would look something like
/*
* Takes each character in inStr and replaces them as necessary based on
* your replacement map. For example, if you see an "n", then replace it with "m"
*/
String normalize(String inStr) {
String newStr;
// something happens
return newStr;
}
If case-sensitivity is not important, then you would again normalize your strings by first converting them to lower-case or upper-case (doesn't matter, as long as it is consistent)

How to parse certain tokens out of a String?

Could someone please help me parse integer values and arithematic operators from a java string.
For ex:
String rule = "itemCount < 10 and itemCount >= 20";
From the rule String I need to retrieve, <, 10, >= and 20 which will then be displayed in the jsp.
for (int i =0; i < rule.length; ++i) {
if (rule[i] == "<") {
// Code for retrieving <
} else if (rule[i] == ">=")
// Code for retrieving >=
} else {
tryParse(rule, i);
}
}
tryParse is the function that will recursively try to parse integers until the biggest sequence of consecutive digits found and updates the value of i
Does a regular expression help you?
Maybe something like:
(\w+) (<|<=|==|>|>=) (\w+) (\w+) (\w+) (<|<=|==|>|>=) (\w+)
(can be optimized for sure)
When matching this expression against your string you should get 7 groups with following contents:
1: itemCount
2: <
3: 10
4: and
5: itemCount
6: >=
7: 20
See the Pattern Class documentation for more details.
But in general I am not sure if this is what you want to do.
Maybe its better to switch to a more abstract way to define your expression instead of writing it into a string.
What about something like this:
Rule rule = Rule.AND(
Rule.SMALLER(itemCount, 10),
Rule.GREATER_OR_EQUAL(itemCount, 20)
);
boolean result = rule.getResult();

How to analyze evenness/oddness of numbers in Java

I have to write a program which reads in 3 numbers (using input boxes), and depending on their values it should write one of these messages:
All 3 numbers are odd
OR
All 3 numbers are even
OR
2 numbers are odd and 1 is even
OR
1 number is odd and 2 are even
This is what I have so far:
import javax.swing.JOptionPane;
class program3
{
public static void main(String[] args)
{
String num1 = JOptionPane.showInputDialog("Enter first number.");
String num2 = JOptionPane.showInputDialog("Enter second number.");
String num3 = JOptionPane.showInputDialog("Enter third number.");
boolean newnum1 = Integer.parseInt(num1);
boolean newnum2 = Integer.parseInt(num2);
boolean newnum3 = Integer.parseInt(num3);
}
}
This is where I am stuck. I am not sure how to use the MOD to display the messages. I think I have to also use an IF Statement too...But I'm not too sure.
Please help! :D
In Java, the modulus operator is %. You can use it like this:
if ( (a % 2) == 0) {
System.out.println("a is even");
}
else {
System.out.println("a is odd");
}
Combine it with some if statements or some counter to implement the final result.
PS: the type of newnumX looks odd :)
I would recommend you to
Start writing down in a piece of paper how would you do it manually.
( Write the algorithm )
Then identify which parts are "programmable" and which ones are not ( identify variables, statements, etc ) .
Try by hand different numbers and see if it is working.
From there we can help you to translate those thoughts into working code ( that's the easy part ).
These are basics programming skills that you have to master.
It is not worth we just answer:
boolean areAllEven = ( one % 2 == 0 ) && ( two % 2 == 0 ) && ( three % 2 == 0 ) ;
boolean areAllOdd = ( one % 2 != ..... etc etc
Because we would be diss-helping you.
Related entry: Process to pass from problem to code. How did you learn?
To avoid big ugly nested IFs, I would declare a small counter (in pseudocode):
if newnum1 mod 2 == 1 then oddcount += 1;
etc...
switch oddcount
case 0:
print "All three numbers are even"
etc...
Just a warning if you choose to use the % operator in Java: if its left-hand operand is negative, it will yield a negative number. (see the language specification) That is, (-5) % 2 produces the result -1.
You might want to consider bitwise operations e.g. "x & 1" to test for even/odd-ness.
Its even simpler than that, you have tree numbers a, b, c
n = a%2 + b%2 +c%2
switch (n):
case 0: 'three are even'
case 1: 'one is odd'
case 2: 'one is even'
case 3: 'three are odd'
And voila!
Write down the basic steps that you have to do to perform the task and then try to implement it in code.
Here is what you have to do:
1 - Get 3 numbers from the user.
2 - You need two variables: one to hold the number of odd inputs and the other to hold the number of the even ones. Lets call these evenCnt and oddCnt. (Hint: Since you know you only have 3 numbers, once you have determined one of these, the other one is just the difference from 3)
3 - Then you need a series of tests (If evenCnt is 3 then show "3 evens", else if ....)
(And Pascal and Kurosch have pretty much given you the fragments you need to fill in steps 2 and 3.)
[Edit: My #2 is wooly-headed. You only need one variable.]
Here you go. I just compiled and ran some test cases through this to confirm it works.
import javax.swing.JOptionPane;
class Program3 {
public static void main(String[] args) {
int evenCount = 0;
for (int i=0; i<3; i++) {
// get the input from the user as a String
String stringInput = JOptionPane.showInputDialog("Enter number " + (i+1) + ".");
// convert the string to an integer so we can check if it's even
int num = Integer.parseInt(stringInput);
// The number is considered even if after dividing by 2 the remainder is zero
if (num % 2 == 0) {
evenCount++;
}
}
switch (evenCount) {
case 3:
System.out.println("All are even");
break;
case 2:
System.out.println("Two are even, one is odd");
break;
case 1:
System.out.println("One is even, two are odd");
break;
case 0:
System.out.println("All are odd");
break;
}
}
}
BTW: I capitalized the class name because it's best practice to do so in Java.
I disagree with alphazero. I don't think two variables are REQUIRED. every number is either ever or odd. So keeping count of one is enough.
As for Asaph's code, I think it is well documented, but if you still want an explanation, here goes:
This is what the for loop does:
It reads (as Strings) user input for the 3 numbers
Integer.parseInt is a function that takes a String as a parameter (for example, '4') and returns an int (in this example, 4). He then checks if this integer is even by modding it by 2. The basic idea is: 4%2 = 0 and 9%2 = 1 (the mod operator when used as a%b gives the remainder after the operation a/b. Therefore if a%2 is 0, then a is even). There is a counter (called evenCount) that keeps track of how many integers are even (based on the %s test).
He then proceeds to do switch statement on the evenCount. A switch statement is sort of like an if-else statement. The way it works is by testing the switch parameter (in this case, evenCount) against the case values (in this case, 3, 2, 1, 0). If the test returns True, then the code in the case block is executed. If there is no break statement at the end of that case block, then, the code in the following case block is also executed.
Here, Asaph is checking to see how many numbers are even by comparing the evenCount to 0, 1, 2, and 3, and then usinga appropriate print statements to tell the user how many even numbers there are
Hope this helps

Categories