In my program I read input from the console and determine whether it is a number or not. Numbers can be any decimal +-. For instance having 123.18p18 is not allowed since there is a nondigit in there, same with -123.18p18. The bad way of doing this (which I am currently doing) is checking if it is a double and catching exceptions, but since I am just parsing a string I think regex is far better to use here. This is my first day in its use (regex) and it seems like an alien language.
I came up with ".*\\D+.*" but that only handles positive numbers.
Edit: Integers are also acceptable.
You are looking for:
"^[+-]?\\d+([.]\\d+)?$"
Optional plus or minus in the beginning, followed by at least one digit. Before the end of the string there can optionally be one dot followed by at least one digit.
To solve your initial problem, you can use the java.util.Scanner class. It provides methods for testing whether the next input is an integer, double, etc., or even testing whether the next input conforms to a given regular expression.
import java.util.Scanner;
//...
Scanner s = new Scanner(System.in);
while ( s.hasNext() ) {
if ( s.hasNextInt() ) {
int i = s.readInt();
// Some work.
} else if ( s.hasNextDouble() ) {
double d = s.nextDouble();
// Some work.
} else if ( s.hasNext(regex) ) {
String t = s.next(regex);
// Some work.
}
// etc.
}
The following regex might work for you;
It defines a pattern which starts with either a + or - followed by zero or more digits and if there is a decimal point, then it must be followed by at least one digit
"^[+-]?\\d+(?:\\.?\\d+)$"
Try double doubleInstance = Double.parseDouble(string); and proceed...
Related
I am working on the problem to find the next greatest number with the same set of digits.
For this I take a integer value input from the user and I want to convert to char array or int array so that I can access individual digits.
But when I take
int value=09 as the input and convert to char array it gives only 9 as it considers it to be octal value. How can I overcome this ?
it is not possible in java to take the int values with leading zeros.
so for the value with leading zeros take it in string format.
but we can insert zeros
int n=7;
String str=String.format("%04d", n); //4 denotes the size of the string
System.out.println(str); // o/p->0007
It is not possible convert a 09 int value to a String of 9 since the value 09 can not be stored in an int.
int is not capable of storing trailing zeros.
Take this sample.
int foo = Integer.valueOf("09");
System.out.println(foo);
Output
9
So to solve your problem you should get a String from the user, validate it and parse it to an Integer[].
Solution
public Integer[] parseToInteger(String number) {
return Arrays.asList(number.toCharArray())
.stream()
.map(c -> Integer.valueOf(c.toString()))
.toArray(size -> new Integer[size]);
}
Now you have an Array of Integer.
Since leading 0's are dropped from integers there is no reason to support assigning such a value to an int.
If I want to convert 9 to '9' I usually just add '0' to it.
You can also do the following:
char c = Character.forDigit(9,10);
If you have a string of characters, you can do the following:
String str = "09";
List<Character> chrs =
str.chars().mapToObj(a -> Character.valueOf((char) a))
.collect(Collectors.toList());
System.out.println(chrs);
Prints
[0,9]
You are asking how to parse a number starting with a leading zero, but I get the feeling that you are actually on the worng track given the problem you are trying to resolve. So let's take one step backward, and lets make sure I understand your problem correctly.
You say that you have to find the "next greatest number with the same set of digits". So you are playing "Scrabble" with digits, trying to find the smalest number composed with the same digits that is strictly greater to the original number. For example, given the input "09", you would output "90", and for "123", you would output "132". Is that right? Let assume so.
Now, the real challenge here is how to determine the smalest number composed with thise digits that is stricly greater to the original number. Actually, there's a few possible strategies:
Enumerate all possible permutations of those digits, then filter out those that are not strictly greater to the original number, and then, among the remaining values, find the smallest value. That would be a very innefficient strategy, requiring both disproportionate memory and processing power. Please, don't consider this seriously (that is, unless you are actually coding for a Quantum Computer ;) ).
Set a variable to the initial number, then iteratively increment that variable by one until you eventually get a number that is composed of the same digits as the original values. That one might look simple to implement, but it actually hides some complexities (i.e. determining that two numbers are composed from the same digits is not trivial, special handling would be required to avoid endless loop if the initial number is actually the greatest value that can be formed with those digits). Anyway, this strategy would also be rather innefficient, requiring considerable processing power.
Iterate over the digits themselves, and determine exactly which digits have to be swapped/reordered to get the next number. This is actually very simple to implement (I just wrote it in less that 5 minutes), but require some thinking first. The algorithm is O(n log n), where n is the length of the number (in digits). Take a sheet of paper, write example numbers in columns, and try to understand the logic behind it. This is definitely the way to go.
All three strategies have one thing in common: they all require that you work (at some point at least) with digits rather than with the number itself. In the last strategy, you actually never need the actual value itself. You are simply playing Scrabble, with digits rather than letters.
So assuming you indeed want to implement strategy 3, here is what your main method might looks like (I wont expand more on this one, comments should be far enough):
public static void main(String[] args) {
// Read input number and parse it into an array of digit
String inputText = readLineFromUser();
int[] inputDigits = parseToDigits(inputText);
// Determine the next greater number
int[] outputDigits = findNextGreaterNumber(inputDigits);
// Output the resulting value
String outputText = joinDigits(outputDigits);
println(outputText);
}
So here's the point of all this discussion: the parseToDigits method takes a String and return an array of digits (I used int here to keep things simpler, but byte would actually have been enough). So basically, you want to take the characters of the input string, and convert that array to an array of integer, with each position in the output containing the value of the corresponding digit in the input. This can be written in various ways in Java, but I think the most simple would be with a simple for loop:
public static int[] parseToDigits(String input) {
char[] chars = input.toCharArray();
int[] digits = new int[chars.length];
for (int i = 0 ; i < chars.length ; i++)
digits[i] = Character.forDigit(chars[i], 10);
return digits;
}
Note that Character.forDigit(digit, radix) returns the value of character digit in base radix; if digit is not valid for the given base, forDigit returns 0. For simplicity, I'm skipping proper validation checking here. One could consider calling Character.isDigit(digit, radix) first to determine if a digit is acceptable, throwing an exception if it is not.
As to the opposite opperation, joinDigits, it would looks like:
public static String joinDigits(int[] digits) {
char[] chars = new char[digits.length];
for (int i = 0 ; i < digits.length ; i++)
chars[i] = Character.digit(digits[i], 10);
return new String(chars);
}
Hope that helps.
For my current code, I'm creating a word calculator where words are inputted to represent numbers and the calculations are done within the code. The requirements is to input two numbers and an operator into the console. I was able to parse the input into three parts, the first number, the operator, and the second number.
My question is how should I approach when I convert the word into number form? For example, if a user inputted:
seven hundred eighty-eight plus ninety-five
How can I turn that into 788 and 95 so I can do the calculations within the code? My input needs to go up to 1000.
This is part of my code for dividing up the input.
import java.util.Scanner;
public class TextCalc2 {
public static void main (String[] args) {
Scanner input = new Scanner(System.in);
String in = input.nextLine();
in = in.toLowerCase();
while (!in.equals("quit")) {
if (in.contains("plus")){
String number1 = in.substring(0, in.indexOf("plus") - 1);
String number2 = in.substring(in.indexOf("plus") + 5, in.length());
String operator = in.substring(in.indexOf("plus"),in.indexOf("plus") + 5);
System.out.println(number1);
System.out.println(operator);
System.out.println(number2);
}
}
First of all there are problems in the way you are splitting the input (you have hard coded the operation). I would suggest splitting your input with " " (space) and then analyzing each part of the input separately.
You will have different types of words in your input, one is a single digit number, double digit number, operations and "hundred".
Then you should find which category first word of your input belongs to, if it has "-" it will be double digit, else look into other categories and search for it till you find it. Then based on category decide what you should do with it, if its a single digit, replace it with its equivalent. if its double digit, split and then replace each digit, if its operation store it and cut your input array from there so that you have separated the first value and second one, and if its hundred multiply previous single digit by 100.
After this parsing steps you will have something like this {"700","88"} , {"95"} and plus operation. now its easy to convert each string to its integer value using parse method and then apply the operation.
BTW, it would be easier to use Enum for your constants and just use their ordinal value. Also use the comment that Jared made for your double digit values.
Let me know if you still have question.
I have created a Fraction Class that does various things such as the addition, multiplication, division, subtraction, greatest common denominator, etc...
There is one part that I am lost on.
I need to make a method that returns a String version of the numerator over the denominator using hyphens to separate them and I need the hyphens to equal the length of the denominator and the numerator to be centered.
For example:
the fraction 3/4 would be 3 with a hyphen under it and the 4 under the hyphen
and something like 5/50000 would be a 5 centered above the 3rd out of 5 hyphens and then the 50000 under the hyphens.
To calculate the number of hyphens that I need, I have come up with:
int hyphenLength = String.valueOf(this.denominator).length();
So far the only thing that I have thought of doing is running a for loop in the String but I am not sure how to do this.
If you are just asking "how to create n-number of hyphens base on an int value", here is some ways you may look into:
There is no direct way in Java to do. You have some way to do, the easiest way is as you said, by a for loop:
for (int i = 0; i < hyphenLength; ++i) {
resultStringBuilder.append('-');
}
Another way is to make use of Arrays.fill():
char[] hyphenArray = new char[hyphenLength];
Arrays.fill(hyphenArray, '-');
String resultString = new String(hyphenArray);
If you can make use of Apache Commons Langs, you can use StringUtils.leftPad() or rightPad():
String resultString = StringUtils.leftPad("myData", hyphenLength, '-');
I have a string that I'm trying to parse into a BigDecimal. I'm using the following regex to strip all non currency symbols with the exception of -,.()$. Once it has been stripped, I'm then trying to create a BigDecimal with the remaining value. The problem begins when a negative value comes across in brackets. Does anybody have any suggestions on how to repair this instance?
(1000.00) fails
I'm assuming I must somehow convert the brackets to a negative sign.
code sample.
public BigDecimal parseClient(Field field, String clientValue, String message) throws ValidationException {
if (clientValue == null) {
return null;
}
try {
clientValue = clientValue.replaceAll( "[^\\d\\-\\.\\(\\)]", "" );
return new BigDecimal(clientValue.toString());
} catch (NumberFormatException ex) {
throw new ValidationException(message);
}
}
You will need to detect the ( and ) characters yourself, then strip them out, create a BigDecimal from the rest of the string, and negate it.
if (clientValue.startsWith('(') && clientValue.endsWith(')'))
{
return new BigDecimal(clientValue.substring(1, clientValue.length() - 1)).negate();
}
else
{
return new BigDecimal(clientValue);
}
What makes you think parentheses are correctly interpreted by BigDecimal? (1000.00) is incorrect input according to the documentation. You must use - symbol (-1000.00). Supported format is strictly defined in JavaDoc. In general it's optional symbol (+ or -) followed by digits, dot (.) and exponent.
For example this is valid input: -1.1e-10.
DecimalFormat is a more appropriate tool for the job:
DecimalFormat myFormatter = new DecimalFormat("¤#,##0.00;(¤#,##0.00)");
myFormatter.setParseBigDecimal(true);
BigDecimal result = (BigDecimal) myFormatter.parse("(1000.00)");
System.out.println(result); // -1000.00 for Locale.US
System.out.println(myFormatter.parse("($123,456,789.12)")); // -123456789.12
As you can see, not only will it deal with negative patterns, but also with currency signs, decimal and grouping separators, localization issues, etc.
Take a look at The Java Tutorials: Customizing Formats for further info.
I'm getting NumberFormatException when I try to parse 265,858 with Integer.parseInt().
Is there any way to parse it into an integer?
Is this comma a decimal separator or are these two numbers? In the first case you must provide Locale to NumberFormat class that uses comma as decimal separator:
NumberFormat.getNumberInstance(Locale.FRANCE).parse("265,858")
This results in 265.858. But using US locale you'll get 265858:
NumberFormat.getNumberInstance(java.util.Locale.US).parse("265,858")
That's because in France they treat comma as decimal separator while in US - as grouping (thousand) separator.
If these are two numbers - String.split() them and parse two separate strings independently.
You can remove the , before parsing it to an int:
int i = Integer.parseInt(myNumberString.replaceAll(",", ""));
If it is one number & you want to remove separators, NumberFormat will return a number to you. Just make sure to use the correct Locale when using the getNumberInstance method.
For instance, some Locales swap the comma and decimal point to what you may be used to.
Then just use the intValue method to return an integer. You'll have to wrap the whole thing in a try/catch block though, to account for Parse Exceptions.
try {
NumberFormat ukFormat = NumberFormat.getNumberInstance(Locale.UK);
ukFormat.parse("265,858").intValue();
} catch(ParseException e) {
//Handle exception
}
One option would be to strip the commas:
"265,858".replaceAll(",","");
The first thing which clicks to me, assuming this is a single number, is...
String number = "265,858";
number.replaceAll(",","");
Integer num = Integer.parseInt(number);
Or you could use NumberFormat.parse, setting it to be integer only.
http://docs.oracle.com/javase/1.4.2/docs/api/java/text/NumberFormat.html#parse(java.lang.String)
Try this:
String x = "265,858 ";
x = x.split(",")[0];
System.out.println(Integer.parseInt(x));
EDIT :
if you want it rounded to the nearest Integer :
String x = "265,858 ";
x = x.replaceAll(",",".");
System.out.println(Math.round(Double.parseDouble(x)));