How to evaluate >9 number in a String expression Java - java

Life is very easy if the expression has values from 0 to 9 but
If expression = 23+52*5 is input by user then I take it in a String named expression.
Now what I want is that a new String or char Array in such a fashion that:
String s or char[] ch = ['23','+','52','*','5']
so that ch[0] or s.charAt(0) gives me 23 and not 2.
To do so I have tried the following and am stuck on what to do next:
for(int i=0;i<expression.length();i++)
{
int operand = 0;
while(i<expression.length() && sol.isOperand(expression.charAt(i))) {
// For a number with more than one digits, as we are scanning
// from left to right.
// Everytime , we get a digit towards right, we can
// multiply current total in operand by 10
// and add the new digit.
operand = (operand*10) + (expression.charAt(i) - '0');
i++;
}
// Finally, you will come out of while loop with i set to a non-numeric
// character or end of string decrement it because it will be
// incremented in increment section of loop once again.
// We do not want to skip the non-numeric character by
// incrementing it twice.
i--;
/**
* I have the desired integer value but how to put it on a string
* or char array to fulfill my needs as stated above.
**/
// help or ideas for code here to get desired output
}
In the while loop the method isOperand(char) is returning a boolean value true if char provided is >=0 or <=9.

You're going to want a String[] when you break the expression apart. Regex lookbehind/lookahead (Java Pattern Reference) allows you to split a String and keep the delimiters. In this case, your delimiters are the operands. You can use a split pattern like this:
public static void main(String[] args) throws Exception {
String expression = "23+52*5";
String[] pieces = expression.split("(?<=\\+|-|\\*|/)|(?=\\+|-|\\*|/)");
System.out.println(Arrays.toString(pieces));
}
Results:
[23, +, 52, *, 5]
One this to consider, is if your expression contains any spaces then you're going to want to remove them before splitting the expression apart. Otherwise, the spaces will be included in the results. To remove the spaces from the expression can be done with String.replaceAll() like this:
expression = expression.replaceAll("\\s+", "");
The "\\s+" is a regular expression pattern that means a whitespace character: [ \t\n\x0B\f\r]. This statement replaces all whitespace characters with an empty space essentially removing them.

String expr = "23+52*5";
String[] operands = expr.split("[^0-9]");
String[] operators = expr.split("[0-9]+");
This breaks it into:

try using a switch case:
//read first character
switch data
if number : what is it ( 0,1,2,3...?)
save the number
if its an operator
save operator
** 2 the switch has 4 cases for operators and 10 for digits **
// read the next character
again switch
if its a number after a number add both chars into a string
if its an operator "close" the number string and convert it into an int
If you will need some code I will gladly help.
Hope the answer is useful.
for i = 1 ; i = string.length
switch :
case 1,2,3,4,5,6,7,8,9,0 (if its a digit)
x(char) = char(i)
case +,-,*,/ (operator)
y(char) = char(i)
x[1] + x[2] +...x[n] = X(string) // build all the digits saves before the operator into 1 string
convert_to_int(X(string))

You can use regex:
\d+
Will grab any instance of one or more consecutive digits.

Related

How to split a string and save the 2 characters that I split with?

I am trying to split a given string using the java split method while the string should be devided by two different characters (+ and -) and I am willing to save the characters inside the array aswell in the same index the string has been saven.
for example :
input : String s = "4x^2+3x-2"
output :
arr[0] = 4x^2
arr[1] = +3x
arr[2] = -2
I know how to get the + or - characters in a different index between the numbers but it is not helping me,
any suggestions please?
You can face this problem in many ways. I´m sure there are clever and fancy ways to split this expression. I will show you the simplest problem-solving process that can help you.
State the problem you need to solve, the input and output
Problem: Split a math expression into subexpressions at + and - signals
Input: 4x^2+3x-2
Output: 4x^2,+3x,-2
Create a pseudo code with some logic you might think works
Given an expression string
Create an empty list of expressions
Create a subExpression string
For each character in the expression
Check if the character is + ou - then
add the subExpression in the list and create a new empty subexpression
otherwise, append the character in the subExpression
In the end, add the left subexpression in the list
Implement the pseudo-code in the programming language of your choice
String expression = "4x^2+3x-2";
List<String> expressions = new ArrayList();
StringBuilder subExpression = new StringBuilder();
for (int i = 0; i < expression.length(); i++) {
char character = expression.charAt(i);
if (character == '-' || character == '+') {
expressions.add(subExpression.toString());
subExpression = new StringBuilder(String.valueOf(character));
} else {
subExpression.append(String.valueOf(character));
}
}
expressions.add(subExpression.toString());
System.out.println(expressions);
Output
[4x^2, +3x, -2]
You will end with one algorithm that works for your problem. You can start to improve it.
Try this code:
String s = "4x^2+3x-2";
s = s.replace("+", "#+");
s = s.replace("-", "#-");
String[] ss = s.split("#");
for (int i = 0; i < ss.length; i++) {
Log.e("XOP",ss[i]);
}
This code replaces + and - with #+ and #- respectively and then splits the string with #. That way the + and - operators are not lost in the result.
If you require # as input character then you can use any other Unicode character instead of #.
Try this one:
String s = "4x^2+3x-2";
String[] arr = s.split("[\\+-]");
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
Personally I like it better to have positive matches of patterns, especially if the split pattern itself is empty.
So for instance you could use a Pattern and Matcher like this:
Pattern p = Pattern.compile("(^|[+-])([^+-]*)");
Matcher m = p.matcher("4x^2+3x-2");
while (m.find()) {
System.out.printf("%s or %s %s%n", m.group(), m.group(1), m.group(2));
}
This matches the start of the string or a plus or minus: ^|[+-], followed by any amount of characters that are not a plus or minus: [^+-]*.
Do note that the ^ first matches the start of the string, and is then used to negate a character class when used between brackets. Regular expressions are tricky like that.
Bonus: you can also use the two groups (within the parenthesis in the pattern) to match the operators - if any.
All this is presuming that you want to use/test regular expressions; generally things like this require a parser rather than a regular expression.
A one-liner for persons thinking that this is too complex:
var expressions = Pattern.compile("^|[+-][^+-]*")
.matcher("4x^2+3x-2")
.results()
.map(r -> r.group())
.collect(Collectors.toList());

Regular Expression Matching for number only with 2 digits repeated

I am trying to match number which are having 2 digits and those are repeated and the length of number is 7 digits .
I want to match these numbers from java .
example numbers:
3433434
6776767
9000999
Please help to create the regular expression for these pattern numbers
I'd recommend hiding any regexes inside helper methods:
private static boolean matchesCriteria(String s) {
return exactlySevenDigits(s) && containsRepeatedDigits(s);
}
private static boolean exactlySevenDigits(String s) {
return s.matches("\\d{7}");
}
private static boolean containsRepeatedDigits(String s) {
return s.matches(".*(\\d)\\1.*");
}
Example results:
3433434 true
6776767 true
9000999 true
1234567 false (no repeating numbers)
12331233 false (too long)
123356A false (not all digits)
You can do it as follows:
String str = "3433434";
boolean sevenOf2Digits = str.length() == 7 &&
str.matches("(\\d)\\1*+(\\d)(\\1|\\2)*");
System.out.println(sevenOf2Digits);
The first (\\d) captures the first digit in group 1.
\\1 is a backreference to group 1, so the first digit. * is 0 or more of those digits, + makes that possessive, which is required to prevent the next (\\d) from matching the same digit.
The following (\\d) captures the second digit in group 2.
(\\1|\\2)* just matches 0 or more of any combination of the first or second digits.
I separated out the length check for simplicity. If you want a pure regex solution, you can add the length check to your regex in the form of a lookahead by adding (?=.{7}$) to the start of your regex.
"(?=.{7}$)(\\d)\\1*+(\\d)(\\1|\\2)*"
With regex it is a little complicated, I would use this way (Java 8+) instead :
boolean check = myString.chars()
.mapToObj(i -> (char) i)
.collect(Collectors.toSet())
.size() == 2;
The idea is to create a Set with the character of this string, if the size of the Set is 2 then it is correct String else it is not.
Or as Ralf Renz mention in comment, you can use this short way :
boolean check = myString.chars().distinct().count() == 2;
So your final solution should look like this :
boolean check = myString.matches("\\d{7}") && myString.chars().distinct().count() == 2;
(?=^.{7}$)(\d)\1*(?!\1)(\d)(?:\1|\2)*
This should do it. It finds a digit and repeats, then finds a second digit and repeats. Then it checks if the rest of the number is one of those 2.
I'll explain in detail what this does.
(?=^.{7}$): Before starting, make sure there are 7 characters between the start and end. If shorter or longer, fast fails.
(\d)\1*(?!\1)(\d): Get the first digit and save it in a capture group. Then matches if the captured digit is also the next one. If there is only a single digit, the next part will catch that. Last digit should always be different then the first one.
(?:\1|\2): repeat the 2 captured digits 0 or more times.
String regex = "[10]{7}|[20]{7}|[21]{7}|[30]{7}|[31]{7}|[32]{7}|[40]{7}|[41]{7}|[42]{7}|[43]{7}|[50]{7}|[51]{7}|[52]{7}|[53]{7}|[54]{7}|[60]{7}|[61]{7}|[62]{7}|[63]{7}|[64]{7}|[65]{7}|[70]{7}|[71]{7}|[72]{7}|[73]{7}|[74]{7}|[75]{7}|[76]{7}|[80]{7}|[81]{7}|[82]{7}|[83]{7}|[84]{7}|[85]{7}|[86]{7}|[87]{7}|[90]{7}|[91]{7}|[92]{7}|[93]{7}|[94]{7}|[95]{7}|[96]{7}|[97]{7}|[98]{7}";
System.out.println(Pattern.matches(regex, "3433434"));
System.out.println(Pattern.matches(regex, "6776767"));
System.out.println(Pattern.matches(regex, "9000999"));
That should do it. All combinations of two digits with a length of 7.

How do I get the last substring starting with +,-,*,/?

If I have expression in a string variable like this 20+567-321, so how can I extract last number 321 from it where operator can be +,-,*,/
If the string expression is just 321, I have to get 321, here there is no operator in the expression
You can do this by splitting your string based on your operators as following:
String[] result = myString.split("[-+*/]");
[+|-|*|/] is Regex that specifies the points from where your string should be split. Here, result[result.length-1] is your required string.
EDIT
As suggested by #ElliotFrisch we need to escape - in regex while specifying it. So following pattern should also work:
String[] result = myString.split("[+|\\-|*|/]");
Here is the list of characters they need to be escaped.
Link.
This seems to be an assignment for learning programming and algo, and also I doubt splitting using Regex would be efficient in a case where only last substring is required.
Start from end, and iterate until the length of the string times.
Declare a empty string say Result
While looping, if any of those operator is found, return Result, else prepend the traversed character to the string Result.
Return Result
String[] output = s.split("[+-/*]");
String ans = output[output.length-1];
Assumption here that there will be no spaces and the string contains only numbers and arithmetic operators.
[+-/*] is a regular expression that matches only the characters we provide inside the square brackets. We are splitting based on those characters.
If you wanna do it with StringTokenizer:
public static void main(String args[])
{
String expression = "20+567-321";
StringTokenizer tokenizer = new StringTokenizer(expression, "+-*/");
int count = tokenizer.countTokens();
if( count > 0){
for(int i=0; i< count; i++){
if(i == count - 1 ){
System.out.println(tokenizer.nextToken());
}else{
tokenizer.nextToken();
}
}
}
}
Recall you can specify multiple delimiters in StringTokenizer.

Replace leading zeros till decimal point with dash

If a string is a = 000102.45600. I need to convert it to a = ---102.45600.
Any help in java using either regex or String formatter?
Tried the following:
a = a.replaceFirst("^0+(?!$)","-");
but i am getting only a = -102.45600 not 3 dashes.
Rules: Any leading zeros before decimal in string should be replaced by that many dashes.
000023.45677 to ----23.45677
002345.56776 to --2345.56776
00000.45678 to -----.45678
Hopefully I am clear on what my need is?
String subjectString = "000102.45600";
String resultString = subjectString.replaceAll("\\G0", "-");
System.out.println(resultString); // prints ---102.45600
\G acts like \A (the start-of-string anchor) on the first iteration of replaceAll(), but on subsequent passes it anchors the match to the spot where the previous match ended. That prevents it from matching zeroes anywhere else in the string, like after the decimal point.
See: reference SO answer.
This should do it:
String number = //assign a value here
for (int i=number.length();i>0; i--) {
if (number.substring(0,i).matches("^0+$")) {
System.out.println(number.replaceAll("0","-"));
break;
}
}
This searches for the longest substring of number which starts at index 0 and consists entirely of zeroes - starting by checking the entire String, then shortening it until it finds the longest substring of leading zeroes. Once it finds this substring, it replaces each zero with a dash and breaks out of the loop.
Why not convert the start of the string to the "." to an integer, convert it back to a string then compare the lengths. 000102 length = 6. 102 length = 3. You would have your preceding zero count.

How do I go through the String to make sure it only contains numbers in certain places?

I am writing something that will take a user's input for a phone number and tell the user if their input was valid or not based on five parameters:
input is 13 characters in length
char at index 0 is '('
char at index 4 is ')'
char at index 8 is '-'
All other characters must be one of the digits: ’0’ through ’9’ inclusive.
So far I have everything down except the 5th parameter. My code for that goes as followed
if (number.contains("[0-9]+"))
{
ints = true;
if (number.contains("[a-zA-Z]*\\d+."))
{
ints = false;
}
}
else
{
ints = false;
}
(Side note: number is my string that is the user's input, and ints is a boolean declared earlier in the code).
Here is a regular expression to do it.
Pattern p = Pattern.compile("^\\(\\d{3}+\\)\\d{3}+-\\d{4}");
System.out.println(p.matcher("(916)628-4563").matches());
System.out.println(p.matcher("( 916 ) 628-4563").matches());
output:
true
false
It can be tough to enter data like this and when receiving user input you should try to limit their options. eg. ask for each part of the phone number, and omit (,) and -.
As the op has added new requirements. First check for the required (,), and -'s.
boolean goodNumber = number.find("(")==0&&number.find(")")==4
goodNumber = goodNumber&&number.find("-")==8
goodNumber = goodNumber&&number.length()==13&&
goodNumber = goodNumber&&number.replaceAll("\\d","").length()==3;
Find the brackets, the dash and then remove all of the numbers and see if you are only left with a bracket and dash.
You can use following. If the string is correct it will print valid, otherwise it will print invalid.
public void compare(){
String inputString="(123)848-3452";
if(inputString.matches("^\\([0-9]{3}\\)[0-9]{3}-[0-9]{4}")){
System.out.println("valid");
}else{
System.out.println("invalid");
}
}
You can have a simple regex like this
Pattern pattern = Pattern.compile("\\(\\d{3}\\)\\d{3}\\-\\d{4}");
Matcher matcher = pattern.matcher("(071)234-2434");
System.out.println(matcher.matches());

Categories

Resources