I want to only accept fractions.
Here's what I've done so far:
if (nm == 2) {
System.out.print("First Fraction: ");
aa = sc.nextLine();
System.out.print("Second Fraction: ");
bb = sc.nextLine();
if (aa.startsWith("[0-9].*") && aa.contains("/") && aa.endsWith("[0-9].*") && bb.startsWith("[0-9].*") && bb.contains("/") && bb.endsWith("[0-9].*")) {
ar = new Arithmetic_Operations(aa, bb);
} else {
System.out.println("Please Input Fraction");
System.out.println();
break;
}
}
Arithmetic_Operations.Add();
How do I detect that the String starts and ends with a number?
Also, I have no idea what I was doing with the .start and .end codes.
The question can be expressed more generally as "how to write a parser". Generally speaking, regex is not the most straightforward way to tackle it. See here for a more thorough explanation, which can be summarized in your case as follows:
Write a method to check that the input has exactly:
a numerator
a denominator
a division sign between them
This is a pretty simple case, so it'd be overkill to write something really complicated for it but one approach without using regex and with three separate simple "functions" (steps) would be the following:
boolean isFraction(String text) {
String[] numeratorAndDenominator = text.split("/");
// check for the division sign
if (numeratorAndDenominator.length != 2) {
return false;
}
// check that the numerator is an integer
try {
Integer.parseInt(numeratorAndDenominator[0].trim());
} catch (NumberFormatException e) {
return false;
}
// check that the denominator is also an integer
try {
Integer.parseInt(numeratorAndDenominator[1].trim());
} catch (NumberFormatException e) {
return false;
}
return true;
}
For more complicated stuff it would probably be more worth your time to look at existing parsing libraries for mathematical expressions. One possibility might be mathparser.
If you want to detect simple fractions, you can use below method.
public static boolean isFraction(String text){
return (text.matches("[0-9]+[/][0-9]+"));
}
If you want a more complex solution, you need to also check,
+, - signs
Parentheses
More than one /
Fractions
If you are implementing these via regex, below link will help you.
Java regex
Related
My current goal is to parse fractions and create improper fractions.
For example:
1_1/3 + 5/3
should come into the console as
4/3 + 5/3
Could someone tell me am I going in the right direction and what should I be focusing on?
import java.util.Scanner;
public class FracCalc {
public static void main (String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Welcome to FracCalc");
System.out.println("Type expressions with fractions, and I will evaluate them.");
boolean isTrue = true;
String in = "";
while(isTrue) {
in = input.nextLine();
if (in.equals("quit")) {
System.out.println("Thanks for running FracCalc!");
isTrue = false;
}else{
System.out.println("You asked me to compute" + in);
}
}
}
public static void parse(String in){
int underscore = in.indexOf("_");
int slash = in.lastIndexOf("/");
String wholenumber = in.substring(0, underscore);
String numerator = in.substring(underscore + 1,slash);
String denominator = in.substring(slash + 1);
if (underscore<0 & slash<0) {
in = wholenumber;
} else if (underscore<0 & slash>0) {
in = in;
} else if (underscore>0 & slash>0) {
} else if (underscore>0 & slash<0) {
in = "Error";
}
}
}
I'd say you're definitely on the right track although I'd consider a bit of a different approach to your parsing.
I would parse the string character by character. Iterate through the string and if your current character is a number, append it to a StringBuffer called "currentNumber" or something. If your current character is not a number you need to decide what to do. If it's an underscore, you know that the value in your currentNumber variable is the whole number part. You could then store that in a separate variable and clear your currentNumber buffer. If your current character is a slash character, you'd know that the value in currentNumber is the numerator of your fraction. If the current character is a space character you can probably just ignore it. If it is a '+' or '-', you'll know that what you have in your currentNumber variable is your fraction denominator. You should then also store the symbol in a separate variable as your "operator". There are numerous ways you could implement this. For example you could have logic that said: "if I have a valid value in my numerator and not in my denominator and the character I'm currently looking at is not a valid numeric character, then I have appended all the digits in my denominator to the currentNumber variable and it should therefore now contain my denominator. So put the value in currentNumber into my denominator variable and move on to the next character".
I hope I haven't lost you completely here... but of course this may be a bit too advanced for what you need to do. For example, you didn't specify the format of the input string, will it always be in the exact same format as you mentioned or can it look different? Can the whole number part have two digits or can it be skipped alltogether?
The method I described above is called a finite state machine and if you haven't learnt about them yet your teacher should probably be impressed if you handed in an assignment using this technique. There is a lot of reading material on FSM so Google is your friend.
But just to be clear. Your solution looks like it would work too, it just probably won't be as "dynamic".
I have this loop that keeps the user stuck inputting values until he/she, inputs something valid, in this case it has to be binary numbers that must be the size of a certain type of variable. Nonetheless, I don't know how to make the loop continue in the case that the user inputs a number made up of something different aside from 1s and 0s.
I was thinking of using string.contains(), but that cannot account for every number. Here's my loop:
while((double)inputStr.length() != table.getNumberOfVariables() ||
inputStr.replaceAll("\\D","").length() != inputStr.length() ||
Double.parseDouble(inputStr) > 1){
This line: Double.parseDouble(inputStr) > 1 was supposed to accomplish that, but I'm dealing with decimal numbers, so if the input is 10 or 100, they're rendered invalid.
In your case, rather than using \D in your regex (anything that's not a digit), you must be more specific: [^01] (meaning: anything not a zero or one).
while((double)inputStr.length() != table.getNumberOfVariables() ||
inputStr.replaceAll("[^01]","").length() != inputStr.length() ||
Double.parseDouble(inputStr) > 1){
It doesn't win you a prize for nice code though, because it is hard for the reader of this code to find out what you are doing. It's better to turn what you're doing into a method with a clear name, like:
public static boolean containsOnly(String s, String only) {
for (int i = 0; i < s.length(); i++) {
if (only.indexOf(s.charAt(i)) == -1)
return false;
}
return true;
}
As it happens, the Apache commons-lang3 library has such a method in it: StringUtils.containsOnly. They have many methods for String manipulation that are clearer and often much faster than using regexes.
You can use a regular expression to validate the binary string:
String s = "0101110";
if (s.matches("[01]++")) {
System.out.println("ok");
} else {
System.out.println("invalid");
}
I have to take an input containing large numbers of order 10^9 in Java. How do I handle Inputs fast? Also since streamtokenizer.nval gives a double, how can I read larger values??
Before parsing, reset the tokenizer syntax table and initialize it to recognize numbers as words:
StreamTokenizer tokenizer = new StreamTokenizer(r);
tokenizer.resetSyntax();
tokenizer.whitespaceChars(0, 32);
tokenizer.wordChars('0', '9');
tokenizer.wordChars('-', '.');
tokenizer.wordChars('+', '+');
tokenizer.wordChars('a', 'z');
tokenizer.wordChars('A', 'Z');
tokenizer.wordChars(0xa0, 0xff); // not really needed here. */
tokenizer.slashSlashComments(true);
tokenizer.slashStarComments(true);
tokenizer.quoteChar('"');
tokenizer.quoteChar('\'');
Then, when encountering a word, you check whether it is parseable as a number (a bit crude here, but it shows the general idea):
...
case StreamTokenizer.TT_WORD:
if ("true".equals(tokenizer.sval)) {
result = Boolean.TRUE;
} else if ("false".equals(tokenizer.sval)) {
result = Boolean.FALSE;
} else if ("null".equals(tokenizer.sval)) {
result = null;
} else {
try {
result = Long.parseLong(tokenizer.sval);
} catch(NumberFormatException e) {
try {
result = Double.parseDouble(tokenizer.sval);
} catch (NumberFormatException e2) {
throw new IllegalStateException(
"Unexpected token: " + tokenizer.toString());
}
}
}
tokenizer.nextToken();
break;
Whether this works depends on the use case: If you want to parse expressions (and not just JSON as in my case), you probably don't want to set + or - as word characters, but the general idea should still work by treating them as unary operators and detecting constants at a later stage.
I'm trying to make a simple calculator and keep on getting the error in the title when I try to make it show "error" if the user doesn't enter one of the given types of operation.
import java.util.Scanner;
public class experiments {
public static void main(String args[]) {
Scanner userInput = new Scanner(System.in);
String operation;
double fNum, sNum, ans;
//select type of operation
System.out.println("Type addition, subtraction, multiplication, or division, then press enter");
operation = userInput.nextLine();
if (operation!=("addition","subtraction","multiplication","division")) {
System.out.println("error");
}
//enter numbers
System.out.println("Enter first number");
fNum = userInput.nextDouble();
System.out.println("Enter second number");
sNum = userInput.nextDouble();
//calculate
if (operation.equals("addition")) {
ans=fNum + sNum;
}
else if (operation.equals("subtraction")) {
ans=fNum - sNum;
}
else if (operation.equals("multiplication")){
ans=fNum * sNum;
}
else if (operation.equals("division")) {
ans=fNum/sNum;
}
//print answer
System.out.println("The answer is ");
System.out.println(ans);
}
}
You can't compare things to a group of objects like this:
operation!=("addition","subtraction","multiplication","division")
Presumably what you want is "if operation is not one of these four things". You've got a few options. The one most like what you have now is to make a new ArrayList (say legalOperations) containing your four legal operations, and then use legalOperations.contains(operation).
However, a cleaner way, which is "better Java", would be to make an enum and use that to do your comparisons.
public enum LegalOperations {
ADDITION,
SUBTRACTION,
MULTIPLICATION,
DIVISION
}
Then you could do your comparisons to your enum (perhaps you'd give the enum a constructor to allow it to have a clear String value for each enum constant, and an isLegalOperation method, for instance).
You should create ArrayList and put value there.
Then you can check if the value exists in the ArrayList.
Like that:
How Arrays.asList(...).contains(...) works?
Java is not capable of understand this command...
if (operation!=("addition","subtraction","multiplication","division")) {
Instead, you need to check each one individually...
if (!"addition".equals(operation) &&
!"subtraction".equals(operation) &&
!"multiplication".equals(operation) &&
!"division".equals(operation)) {
// Handle error...
}
if (operation!=("addition","subtraction","multiplication","division")) is incorrect comparison in Java. Use switch statement if you are using Java 7 or string.equals method with multiple if statements.
You can use the contains method like this:
String[] operations = {"addition","subtraction","multiplication","division"};
if(!operations.contains(operation)) {
...
I think you can rewrite the same as
if (!( operation.equals("addition") || operation.equals("subtraction") ||
operation.equals("multiplication") || operation.equals("division"))) {
System.out.println("error");
}
There is one more Easy way of doing it which involves writing less
as you have an array of Strings, Declare it as an array
String [] operations = {"addition", "subtraction", "multiplication", "division"};
then use this to check
if(!Arrays.asList(operations).contains(operation)) {
System.out.println("error");
}
This question already has answers here:
What's the best way to check if a String represents an integer in Java?
(40 answers)
Closed 9 years ago.
I'm trying to determine if a particular item in an Array of strings is an integer or not.
I am .split(" ")'ing an infix expression in String form, and then trying to split the resultant array into two arrays; one for integers, one for operators, whilst discarding parentheses, and other miscellaneous items. What would be the best way to accomplish this?
I thought I might be able to find a Integer.isInteger(String arg) method or something, but no such luck.
The most naive way would be to iterate over the String and make sure all the elements are valid digits for the given radix. This is about as efficient as it could possibly get, since you must look at each element at least once. I suppose we could micro-optimize it based on the radix, but for all intents and purposes this is as good as you can expect to get.
public static boolean isInteger(String s) {
return isInteger(s,10);
}
public static boolean isInteger(String s, int radix) {
if(s.isEmpty()) return false;
for(int i = 0; i < s.length(); i++) {
if(i == 0 && s.charAt(i) == '-') {
if(s.length() == 1) return false;
else continue;
}
if(Character.digit(s.charAt(i),radix) < 0) return false;
}
return true;
}
Alternatively, you can rely on the Java library to have this. It's not exception based, and will catch just about every error condition you can think of. It will be a little more expensive (you have to create a Scanner object, which in a critically-tight loop you don't want to do. But it generally shouldn't be too much more expensive, so for day-to-day operations it should be pretty reliable.
public static boolean isInteger(String s, int radix) {
Scanner sc = new Scanner(s.trim());
if(!sc.hasNextInt(radix)) return false;
// we know it starts with a valid int, now make sure
// there's nothing left!
sc.nextInt(radix);
return !sc.hasNext();
}
If best practices don't matter to you, or you want to troll the guy who does your code reviews, try this on for size:
public static boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
} catch(NullPointerException e) {
return false;
}
// only got here if we didn't return false
return true;
}
It's better to use regular expression like this:
str.matches("-?\\d+");
-? --> negative sign, could have none or one
\\d+ --> one or more digits
It is not good to use NumberFormatException here if you can use if-statement instead.
If you don't want leading zero's, you can just use the regular expression as follow:
str.matches("-?(0|[1-9]\\d*)");
Or you can enlist a little help from our good friends at Apache Commons : StringUtils.isNumeric(String str)
You want to use the Integer.parseInt(String) method.
try{
int num = Integer.parseInt(str);
// is an integer!
} catch (NumberFormatException e) {
// not an integer!
}
Or simply
mystring.matches("\\d+")
though it would return true for numbers larger than an int
As an alternative approach to trying to parse the string and catching NumberFormatException, you could use a regex; e.g.
if (Pattern.compile("-?[0-9]+").matches(str)) {
// its an integer
}
This is likely to be faster, especially if you precompile and reuse the regex.
However, the problem with this approach is that Integer.parseInt(str) will also fail if str represents a number that is outside range of legal int values. While it is possible to craft a regex that only matches integers in the range Integer.MIN_INT to Integer.MAX_INT, it is not a pretty sight. (And I am not going to try it ...)
On the other hand ... it may be acceptable to treat "not an integer" and "integer too large" separately for validation purposes.
You can use Integer.parseInt(str) and catch the NumberFormatException if the string is not a valid integer, in the following fashion (as pointed out by all answers):
static boolean isInt(String s)
{
try
{ int i = Integer.parseInt(s); return true; }
catch(NumberFormatException er)
{ return false; }
}
However, note here that if the evaluated integer overflows, the same exception will be thrown. Your purpose was to find out whether or not, it was a valid integer. So its safer to make your own method to check for validity:
static boolean isInt(String s) // assuming integer is in decimal number system
{
for(int a=0;a<s.length();a++)
{
if(a==0 && s.charAt(a) == '-') continue;
if( !Character.isDigit(s.charAt(a)) ) return false;
}
return true;
}
You can use Integer.parseInt() or Integer.valueOf() to get the integer from the string, and catch the exception if it is not a parsable int. You want to be sure to catch the NumberFormatException it can throw.
It may be helpful to note that valueOf() will return an Integer object, not the primitive int.
public boolean isInt(String str){
return (str.lastIndexOf("-") == 0 && !str.equals("-0")) ? str.substring(1).matches(
"\\d+") : str.matches("\\d+");
}