Problem: Java program to split the coefficients from a quadratic equation eg
if input string is:
String str1;
str1 = "4x2-4x-42=0"
So I need to split the coefficients from the given input string and to get output as
a = 4 b = -4 c = -42
I tried this:
String equation = "ax2+bx-c=0";
String[] parts = equation.split("\\+|-|=");
for (int i = 0; i < parts.length - 2; i++) {
String part = parts[i].toLowerCase();
System.out.println(part.substring(0, part.indexOf("x")));
}
System.out.println(parts[2]);
But I got the output as 23x2 and 4x and 4.
Actual output needed is 23 ,- 4 , 4.
Use Regex, the following pattern will work:
([+-]?\d+)[Xx]2\s*([+-]?\d+)[Xx]\s*([+-]?\d+)\s*=\s*0
This will match the quadratic and extract the parameters, lets work out how it works:
(...) this is capturing group
[+-]?\d+ this matches a number of digits, preceded optionally by a + or -
[Xx] this matches "X" or "x"
\s* this matches zero or more spaces
So
([+-]?\d+) matches the "a" argument
[Xx]2 matches "X2" or "x2"
\s* matches optional whitespace
([+-]?\d+) matches the "b" argument
[Xx] matches "X" or "x"
\s* matches optional whitespace
([+-]?\d+) matches the "c" argument
\s*=\s*0 matches "=0" with some optional spaces
Lets wrap this in a class:
private static final class QuadraticEq {
private static final Pattern EQN = Pattern.compile("([+-]?\\d+)[Xx]2\\s*([+-]?\\d+)[Xx]\\s*([+-]?\\d+)\\s*=\\s*0");
private final int a;
private final int b;
private final int c;
private QuadraticEq(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}
public static QuadraticEq parseString(final String eq) {
final Matcher matcher = EQN.matcher(eq);
if (!matcher.matches()) {
throw new IllegalArgumentException("Not a valid pattern " + eq);
}
final int a = Integer.parseInt(matcher.group(1));
final int b = Integer.parseInt(matcher.group(2));
final int c = Integer.parseInt(matcher.group(3));
return new QuadraticEq(a, b, c);
}
#Override
public String toString() {
final StringBuilder sb = new StringBuilder("QuadraticEq{");
sb.append("a=").append(a);
sb.append(", b=").append(b);
sb.append(", c=").append(c);
sb.append('}');
return sb.toString();
}
}
Note the \\, this is required by Java.
A quick test:
System.out.println(QuadraticEq.parseString("4x2-4x-42=0"));
Output:
QuadraticEq{a=4, b=-4, c=-42}
If you are only using quadratics:
int xsqrd = equation.indexOf("x2");
int x = equation.indexOf("x", xsqrd);
int equ = equation.indexOf("=");
String a = equation.subString(0,xsqrd);
String b = equation.subString(xsqrd+1,x);
String c = equation.subString(x,equ);
I may have messed up the substrings but you get the general idea.
The first note: if you use symbol as delimiter in regexp, you will lose it in slpitted elements. I suggest you use the folllowing regexp:
"x2|x|="
Then, you can got only numbers.
The full fragment of code is:
public class Main {
private static final char[] varNames = {'a', 'b', 'c'};
public static void main(String[] args) {
String equation = "4x2-4x-42=0";
String[] parts = equation.split("x2|x|=");
// you will get 4 elements, but the last element is always 0
for(int i=0; i<parts.length - 1; i++){
System.out.println(varNames[i] + " = " + Integer.parseInt(parts[i]));
}
}
}
But in this case you will have the '+' symbols in output. To avoid it, you may use Integer.parseInt(parts[i]) instead of parts[i].
for ( int i = 0 ; i < str.length ; ++i ){
if(asciiOf(str.charAt(i)) == asciiOfIntegerValue ){
addCharInArrayList(str.charAt(i));
}else{
addInFuncList();
addCharInArrayList("_");
}
// join numbers which are not separated by _ and apply BODMAS rule and solve it
// fyi : apologies - very inefficient pseudocode, wrote in a haste
You can use a regex as follows:
final String regex = "([+-]?\\d+)x2([+-]\\d+)x([+-]\\d+)=0";
Pattern pattern = Pattern.compile(regex);
final String equation = "4x2-4x-42=0";
Matcher matcher = pattern.matcher(equation);
if (matcher.matches()) {
int a = Integer.parseInt(matcher.group(1));
int b = Integer.parseInt(matcher.group(2));
int c = Integer.parseInt(matcher.group(3));
System.out.println("a=" + a + " b=" + b + " c=" + c);
}
Output:
a=4 b=-4 c=-42
Related
I'm trying to swap the parentheses in the String A * (B + C) / D, but swapping them, results in A * \)B + C( / D instead of A * )B + C( / D.
public class InfixToPrefixExpression {
private String swapStrings(String expression, String one, String two){
return Arrays.stream(expression.split(one, -1))
.map(s -> s.replaceAll(two, one))
.collect(Collectors.joining(two));
}
public static void main(String[] args) {
String expression = "A * (B + C) / D";
String result = new InfixToPrefixExpression().swapStrings(expression,
"\\(","\\)");
System.out.println(result);
}
}
How do I remove the extra back-slash that appears in the resulting string? I tried the following as well, but the String.join() method adds the extra slash in the result.
// String[] split = expression.split(one, -1);
// for (int i = 0; i < split.length; i++) {
// split[i] = split[i].replaceAll(two, one);
// }
// String result = String.join(two, split);
An easy method of swapping may be to swap "(" for a special character like "_", then swap ")" for "(" and finally "_" for ")" like this:
final String expression = "A * (B + C) / D";
final String result = expression
.replace("(", "_")
.replace(")", "(")
.replace("_", ")");
If you don't want to use a special character, you can do a trick with splitting the expression by one bracket like this:
final String expression = "A * (B + C) / D";
final String[] substrings = expression.split("\\(");
final List<String> replacedSubstrings = new ArrayList<>();
for (String substring : substrings) {
replacedSubstrings.add(substring.replace(")","("));
}
final String result = String.join(")", replacedSubstrings);
You might need to provide special values to be used in regular expressions and in Collectors.joining:
private static String swapStrings(String expression, String one, String two){
String reOne = "\\" + one;
String reTwo = "\\" + two;
return Arrays.stream(expression.split(reOne, -1))
.map(s -> s.replaceAll(reTwo, one))
.collect(Collectors.joining(two));
}
Then this method may be called without escaping parentheses:
String expression = "A * (B + C) / D";
String result = swapStrings(expression, "(",")");
System.out.println(result);
Output:
A * )B + C( / D
What is the best way to increment an Int by 1 at position X in a String.
For example, if I am trying to web scrape hundreds of URL's all containing a single number, how do you increment from a root url to a higher value.
www.scrapeme1.com (Root URL)
www.scrapeme2.com
...
.....
www.scrapeme150.com
Please see my best code attempt below.
static final Pattern NUMBER_PATTERN = Pattern.compile("\\d+");
static String increment(String s) {
Matcher m = NUMBER_PATTERN.matcher(s);
if (!m.find())
throw new NumberFormatException();
String num = m.group();
int inc = Integer.parseInt(num) + 1;
String incStr = String.format("%0" + num.length() + "d", inc);
return m.replaceFirst(incStr);
}
#Test
public static void testIncrementString() {
System.out.println(increment("ABC123")); // -> ABC124
System.out.println(increment("Z00000")); // -> Z00001
String url = "https://www.w3resource.com/csharp-exercises/basic/csharp-basic-exercise-3.php";
System.out.println(increment(url)); // -> https://www.w3resource.com/csharp-exercises/basic/csharp-basic-exercise-3.php
}
Assuming the number is always what immediately precedes the domain, you could take a regex approach to separate the input URL into a first part, coming before the final number, the number itself, and the domain. Then, iterate in a loop and piece together the URL outputs you want to see.
String url = "https://www.w3resource.com/csharp-exercises/basic/csharp-basic-exercise-3.php";
String part1 = url.replaceAll("\\d+\\.[^.]+$", "");
String number = url.replaceAll("^.*(\\d+)\\.[^.]+$", "$1");
String part2 = url.replaceAll("^.*\\d+(\\.[^.]+)$", "$1");
int numStart = Integer.parseInt(number);
for (int i=0; i < 5; ++i) {
String urlNew = part1 + (numStart + i) + part2;
System.out.println(urlNew);
}
This prints:
https://www.w3resource.com/csharp-exercises/basic/csharp-basic-exercise-3.php
https://www.w3resource.com/csharp-exercises/basic/csharp-basic-exercise-4.php
https://www.w3resource.com/csharp-exercises/basic/csharp-basic-exercise-5.php
https://www.w3resource.com/csharp-exercises/basic/csharp-basic-exercise-6.php
https://www.w3resource.com/csharp-exercises/basic/csharp-basic-exercise-7.php
I have this number: 4200000000000000
I would like to leave only the first 4 digits and last 3 digits:
42000......000
Everything else should be replaced by dots. How I can implement this with some smart algorithm?
Why not use a StringBuilder and the substring method:
public static String foo(long num) {
String numToString = String.valueOf(num);
return new StringBuilder()
.append(numToString.substring(0 , 4))
.append("....")
.append(numToString.substring(numToString.length()-3, numToString.length()))
.toString();
}
When inputted 4200000000000000 it outputs:
4200....000
Or if the input is already a String:
public static String foo(String str) {
return new StringBuilder()
.append(str.substring(0 , 4))
.append("....")
.append(str.substring(str.length()-3, str.length()))
.toString();
}
Parse your number into a string and try this:
int last = 3;
int first = 4;
String number = '4200000000000000';
String start = number.substring(0,first-1);
String end = number.substring(number.length()-last,number.length()-1);
String dots = '';
for(int i = 0; i<number.length()-last-first;i++){
dots = dots + '.';
}
String result = start + dots + end;
You can use something like this,
public class Main {
public static void main(String[] args) {
System.out.println(convert("4200000000000000", 4, 3));
}
static String convert(String number, int firstDigits, int lastDigits) {
String first = number.substring(0, firstDigits);
String middle = number.substring(firstDigits, number.length() - lastDigits).replaceAll("0", ".");
String last = number.substring(number.length() - lastDigits, number.length());
return first + middle + last;
}
}
You could convert it to a char array, alter it, then convert it back into a string
char[] charArray = originalNumber.toCharArray();
for (int i; i < charArray.length; i++) {
if (i <= 4 || i >= charArray.length - 3) {
charArray[i] = ".";
}
}
String outputString = new String(charArray);
This will replace all chars from the 4th char up to the 4th from the end with '.':
String start = "4200000000000000";
System.out.println(start);
String target = start;
if (start.length() > 7) {
target = new StringBuilder()
.append(start.substring(0, 4))
.append(new String(new char[start.length() - 7]).replaceAll(".", "."))
.append(start.substring(start.length() - 3))
.toString();
}
System.out.println(target);
will print
4200000000000000
4200.........000
Using substring method of the String class :
String str = "4200000000000000";
String res = str.substring(0,4)+ str.substring(4,str.length()-3).replaceAll(".", ".") + str.substring(str.length()-3);
If you are using Apache commons library, you can use repeat method to create masking string of specified length and the overlay method of StringUtils class to overlay part of the String :
String str = "4200000000000000";
String mask= StringUtils.repeat('.', str.length()-7);
String res = StringUtils.overlay(str, mask, 4, str.length()-3);
My task is splitting a string, which starts with numbers and contains numbers and letters, into two sub-strings.The first one consists of all numbers before the first letter. The second one is the remained part, and shouldn't be split even if it contains numbers.
For example, a string "123abc34de" should be split as: "123" and "abc34de".
I know how to write a regular expression for such a string, and it might look like this:
[0-9]{1,}[a-zA-Z]{1,}[a-zA-Z0-9]{0,}
I have tried multiple times but still don't know how to apply regex in String.split() method, and it seems very few online materials about this. Thanks for any help.
you can do it in this way
final String regex = "([0-9]{1,})([a-zA-Z]{1,}[a-zA-Z0-9]{0,})";
final String string = "123ahaha1234";
final Pattern pattern = Pattern.compile(regex);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
matcher.group(1) contains the first part and matcher.group(2) contains the second
you can add it to a list/array using these values
You can use a pretty simple pattern : "^(\\d+)(\\w+)" which capture digits as start, and then when letters appear it take word-char
String string = "123abc34de";
Matcher matcher = Pattern.compile("^(\\d+)(\\w+)").matcher(string);
String firstpart = "";
String secondPart = "";
if (matcher.find()) {
firstpart = matcher.group(1);
secondPart = matcher.group(2);
}
System.out.println(firstpart + " - " + secondPart); // 123 - abc34de
This is not the correct way but u will get the result
public static void main(String[] args) {
String example = "1234abc123";
int index = 0;
String[] arr = new String[example.length()];
for (int i = 0; i < example.length(); i++) {
arr = example.split("");
try{
if(Integer.parseInt(arr[i]) >= 0 & Integer.parseInt(arr[i]) <= 9){
index = i;
}
else
break;
}catch (NumberFormatException e) {
index = index;
}
}
String firstHalf = example.substring(0,Integer.parseInt(arr[index])+1);
String secondHalf = example.substring(Integer.parseInt(arr[index])+1,example.length());
System.out.println(firstHalf);
System.out.println(secondHalf);
}
Output will be: 1234 and in next line abc123
I have this String: "player.login name=username;x=52;y=406" how would I be able to split it so I easily could do Player pl = new Player(name, x, y) ?
I tried with a regex that looks like this: "([a-zA-Z_]+)[=]{1}([a-zA-Z0-9_]+)[;]{1}" but I'm not very good at regexs so it didn't work.
EDIT: Someone came up with a good solution so no need to comment. :)
What I used:
public static void main(String args[]) {
String login = "player.login name=username;x=52;y=406";
String str = login.substring("player.login".length() + 1);
String[] sp = str.split(";");
Player player = new Player("", 0, 0);
for (String s : sp) {
String[] a = s.split("=");
if (a[0].equals("name")) player.username = a[1];
else if (a[0].equals("x")) player.x = toInt(a[1]);
else if (a[0].equals("y")) player.y = toInt(a[1]);
}
System.out.println("Player: " + player.username + " # " + player.x + ", " + player.y);
}
public static int toInt(String s) {
return Integer.parseInt(s);
}
This should work (you should add bound checks before calling exp.split("=")[1]):
public static void main(String[] args) {
String s = "player.login name=username;x=52;y=406";
String[] expressions = s.split(";");
for (String exp : expressions) {
System.out.println(exp.split("=")[1]);
}
}
Since Java 7 there is support for named capturing groups, would be a nice usage here
String s = "player.login name=username;x=52;y=406";
Pattern p = Pattern.compile("name=(?<UserName>[^;]+);" + // Match the UserName in the Named Group "UserName", matching at least one non semicolon
"x=(?<x>\\d+);" + // Match the value of x in the Named Group "x", matching at least one digit
"y=(?<y>\\d+)" // Match the value of y in the Named Group "y", matching at least one digit
);
Matcher m = p.matcher(s);
if (m.find()) {
System.out.println(m.group("UserName"));
System.out.println(m.group("x"));
System.out.println(m.group("y"));
}
You could use String.split() three times, splitting on a space, then semicolon, then =. Or assylia's answer does it with two splits - best solution rather depends on whether you want to validate the parts of the text you are discarding.
Or using regex...
String regex = ".+=(\\w+);x=(\\d+);y=(\\d+)"
...which you can run with the following code:
Pattern p = Pattern.compile(".+=(\\w+);x=(\\d+);y=(\\d+)");
Matcher m = p.matcher("player.login name=username;x=52;y=406");
m.find();
System.out.println(m.group(1) + "," + m.group(2) + "," + m.group(3));
Or you can try with Guava:
String data = "player.login name=username;x=52;y=406";
List<String> fields = ImmutableList.copyOf(Splitter.on(' ').limit(2).split(data));
String type = fields.get(0);
Map<String, String> properties = Splitter.on(';').trimResults().withKeyValueSeparator("=").split(fields.get(1));
Try using a Pattern instead:
public static void main(String args[]){
String str = "player.login name=username;x=52;y=406";
Pattern p = Pattern.compile("^player\\.login name=(.+);x=(\\d+);y=(\\d+)$");
Matcher m = p.matcher(str);
Player player;
if (m.matches()){
String name = m.group(1);
int x = Integer.parseInt(m.group(2));
int y = Integer.parseInt(m.group(3));
System.out.println(name);
System.out.println(x);
System.out.println(y);
player = new Player(name, x, y);
} else {
player = null;
}
// Do stuff with player.
}