I am writing a program to add and subtract user inputted polynomials but I ran into trouble dealing with negative numbers. The program will work fine with positive numbers but I get the following output with negative numbers.
Output:
Coeficent: -2x^-2+3
Coeficent: 6
Exponent: 0
Exponent: 0
Exponent: 0
Exponent: 1
Exponent: 0
Code:
Scanner in = new Scanner(System.in);
LinkedList list = new LinkedList();
String polynomial= "-2x^-2+3x^1+6";
String[] parts = polynomial.split("x\\^\\d+\\+?");
for (String part : parts) {
System.out.println("Coeficent: " + part);
}
String[] terms = polynomial.split("(-|\\+)");
for (String term : terms) {
String[] exponent = term.split("\\^");
System.out.println("Exponent: " + (exponent.length > 1 ? exponent[1] : "0"));
}
Here's an example that separates out the two parts of each term:
public static void main(String ...args) {
Pattern termPat = Pattern.compile("([+-]?(\\d+|(?=x)))(x(\\^([+-]?(\\d+)))?)?");
System.out.println("Input: " + polynomial);
int pos = 0;
Matcher m = termPat.matcher(polynomial);
while (true) {
if (!m.find(pos))
break;
int coeff = Integer.parseInt(m.group(1) + (m.group(2).length() == 0 ? "1" : ""));
int degree = Integer.parseInt((m.group(3) == null)? "0" : (m.group(5) == null)? "1" : m.group(5));
System.out.println(String.format("Term - Coeff: %d Degree: %d", coeff, degree));
pos = m.end();
}
}
Output:
Input: -2x^-2+3x^1+6
Term - Coeff: -2 Degree: -2
Term - Coeff: 3 Degree: 1
Term - Coeff: 6 Degree: 0
You could expand on using a regular expression for splitting input.
Using the regex: ((?:[\-\+]\dx\^[\-\+]\d)|[\-\+]\d) will give you a proper start to capture polynomials with all +/- signs written out. For example: +2x^+2+3x^+1+4x^-3+6 would be an accepted input. You would then interate through the matches and process each for themself. The example before will give you the following matches:
+2x^+2
+3x^+1
+4x^-3
+6
try it out here
Consider sequence of mathematical operations. Split step-by-step:
first, split additions/subtractions, but here check if your finding has a left-operand. If there is no left-operand, it's a sign instead of an operation.
So, identify those +/- which do have a number or a variable on its left side, but NO operatator.
Then, split multiplications and divisions
Finally, split for those operations with highest priority - in your case, exponential function
Related
I coded a simple solution which multiplied 2 integers given as strings and returned the product as a string. But it doesn't work for big values and I'm not allowed to use the Big-Integer library.
This is my current solution.
class Solution {
public String multiply(String num1, String num2) {
int numOne = 0;
int numTwo = 0;
for(char c : num1.toCharArray()){
if((int)(c-'0') >= 0 && (int)(c-'0') <= 9){
numOne = numOne*10 + (int)(c-'0');
}
}
for(char c : num2.toCharArray()){
if((int)(c-'0') >= 0 && (int)(c-'0') <= 9){
numTwo = numTwo*10 + (int)(c-'0');
}
}
return numOne*numTwo + "";
}
}
I got an error in the following test case:
Input:
"123456789"
"987654321"
Output:
"-67153019"
Expected:
"121932631112635269"
What changes should I make so as to be able to multiply large numbers also?
For this, you can refer to the Karatsuba Multiplication algorithm.
You can do this too.
If any of the numbers is negative pick up from substring 1 to n.
Start from the last digit of second number.
Multiply it with the first number. store the result.
Do it with all the numbers of the second numbers and keep adding the result of the previous step to current step with ith shift in the position.
There are samples of this solution too on the internet. You will find it.
int a=1256;
int b=34;
Now i want to print as below.
System.out.println(**First two digit from (a)** +b+ **and last two digit from (a)**);
help me out of this!
You might want to use Integer.toString(value) and than print the substring.
Something like that:
Integer a = new Integer(1256);
String aStr = a.toString();
System.out.println(aStr.substring(0,2));
The first digit of an int can be given with a while loop : divide by 10 until you're under 10, or use the String version which is easier to use
1st digit : String.valueOf(number).charAt(0)
last digit : number%10
Then concatenate them all, the ""+ is to avoid mathematic sum between them
System.out.println("" + String.valueOf(a).charAt(0) + b + (a%10)) ;
Since we need first 2 digits we should divide it by 100.
For the last 2 digits, apply mod 100 on the given number to get remainder which is the last 2 digits.
public class Main
{
public static void main(String[] args) {
int a=1256;
int b=34;
System.out.println(a/100+"" +b+ ""+a%100); // Output: 123456
System.out.println(a/100+" " +b+ " "+a%100); // Output: 12 34 56
}
}
The first System.out.println is without spaces and the second System.out.println is with spaces.
I have a main function that calls another function and passes the given number as a parameter. In the other function, I want to break up the given number into sums of power. How can this be done?
My code looks like:
public static void main()
{
String hello=raisetopower(in.nextInt());
}
public String raisetopower(int n)
{
// do the logic
}
Explanation :
say if the number is 25: the function should return 5^2 + 0^2
and if it is 26: 5^2+1^2
I agree with Richard's comment that this more Mathematics than Java
The question needs more information to be able to provide code to assist, such as whether or not you consider a maximum base like 10 and whether or not all bases should be in the output even if they are to the power of 0 as your example is confusing:
"say if the number is 25: the function should return 5^2 + 0^2 and if
it is 26: 5^2+1^2"
However with that in mind, hopefully this example will be able to assist
Assuming you do have a maximum base being considered, you could start from the highest base to the lowest and use logs
If the result of the log is greater than or equal to 1, then this value should be in the output, so subtract that value and continue on to the next base
Keep continuing until you hit a value of exactly 1 and that should be your end condition
E.g assuming a maximum base of 5 for this example with an input of 27
log5 27 = 2.04781858346
so we will have 5^2 in the output and subtract this from the input, you could use floor to extract the '2'
log4 2 = 0.5
less than one so not an integer power
log3 2 = 0.630929753571
less than one so not an integer power
log2 2 = 1
add to output as greater than or equal to 1 and terminate as it is exactly 1
If you're only displaying bases with powers greater than or equal to one (this was unclear), your output at this point would be:
27 = 25^2 + 2^1
You could use a StringBuilder or an ordered collection of custom objects holding your bases and powers to make it easier to generate the output
Here's an SSCCE for my above algorithm:
import java.util.Scanner;
public class NumberToPowerConversion {
public static void main(String[] args) {
int maxBaseToConsider = 5;
System.out.println("Input number to convert: ");
Scanner input = new Scanner(System.in);
int number = input.nextInt();
StringBuilder output = new StringBuilder("Represented as powers: " + number + " = ");
for(int base = maxBaseToConsider; base >= 1; base--){
//Prevent division by 0 (log 1)
double logResult = base > 1 ? Math.log(number) / Math.log(base) : 1;
int floorResult = (int)Math.floor(logResult);
if(number == 1 || logResult == 1.0){
output.append(base + "^" + floorResult);
number -= Math.pow(base, floorResult);
if(number != 0){
//If the number couldn't be broken down completely, add the remainder to the output
output.append(" + " + number + "^1"); //To keep format consistent
}
break; //end condition reached
}
else if(floorResult >= 1){
output.append(base + "^" + floorResult);
number -= Math.pow(base, floorResult);
if(number == 0){ break; }
else{ output.append(" + "); }
}
}
System.out.println(output.toString());
}
}
Example output:
Represented as powers: 27 = 5^2 + 2^1
Represented as powers: 77 = 5^2 + 4^2 + 3^3 + 2^3 + 1^1
Represented as powers: 234 = 5^3 + 4^3 + 3^3 + 2^4 + 1^1 + 1^1
Represented as powers: 99 = 5^2 + 4^3 + 3^2 + 2^0
Represented as powers: 1 = 5^0
I have actually found the solution of this problem over here : https://github.com/Widea/Interview-Questions/blob/master/Hard/Random/PowerNumbers.java
/* Algorithm :
i <- square root of n
while n<1
n <- n-square of i
r <- r concatenate with i^2
if n=0 r concatenate with i^0
if n=1 r concatenate with i^1
i <- square root of n
return r
*/
public static String raisetopower(int n){
String raised="";
int i=(int)Math.sqrt(n);
while(n>1){
n=n-(int)Math.pow(i,2);
raised+=String.valueOf(i)+"^2+";
if(n==0)
raised+="0^2";
if(n==1)
raised+="1^2";
i=(int)Math.sqrt(n);
}
return raised;
}
I'm trying to extract the first number from expressions:
Here's my code for while:
String[] strArray = input.split("\\+ ");
double[] numbers = getNumbersFromString();
public static double[] getNumbersFromString() {
double[] numbers = new double[strArray.length];
for (int i = 0; i < strArray.length; i++) {
numbers[i] = Double.parseDouble(strArray[i].replaceAll("\\D", ""));
}
return numbers;
}
Inputs and their expected outputs:
Z = 4x1 + 3x2 + 6x3 // 4 3 6
Z = 24x1 + 33x2 + 68x3 // 24 33 68
Z = 412x1 + 309x2 + 612x3 // 412 309 612
Z = 4329x1 + 3901x2 + 6716x3 // 4329 3901 6716
Actually, it's removing but it retrieves besides the first number, the second also. Eg.(In the first case): // 41 32 63, while it should be only // 4 3 6.
I could do something like "\\w = |x\\d", "", but it will only work for this specific case, I want a more general thing.
Thanks in advance.
Edit:
I got the following answer for the original question:
String input = "Z = 4329x1 + 3901x22 + 6716x3";
input = input.replaceAll("^\\D+", "");
double[] numbers = Pattern.compile("x\\d+\\D*")
.splitAsStream(input)
.mapToDouble(Double::parseDouble)
.toArray();
But now appeared a new thing to be done. Inputs that has no numbers before the x1/x2/x3.. or any kind of this" should be replaced by the number "1".
Some inputs and their respective expected outputs:
Z = x11 + x2 + x90 // 1 1 1
Z = 2x1 + 2x4 + x9 // 2 2 1
By the way, I have made this regex: (?<!\d)x\d+.
Then I modified the code to:
return Pattern.compile("x\\d+\\D*")
.splitAsStream(input.replaceAll("(?<!\\d)x\\d+","1").replaceAll("^\\D+", ""))
.mapToDouble(Double::parseDouble)
.toArray();
But it's returning me `java.lang.NumberFormatException: For input string: "1 + 3".
PS: it should work for either the old and new case.
This should work as required:
String s = "Z = 4329x1 + 3901x22 + 6716x3";
String[] split = s.replaceAll("^\\D+", "").split("x\\d+\\D*");
System.out.println(Arrays.toString(split)); //[4329, 3901, 6716]
With streams you could do something like this to obtain your array of doubles:
String input = "Z = 4329x1 + 3901x22 + 6716x3";
input = input.replaceAll("^\\D+", "");
double[] numbers = Pattern.compile("x\\d+\\D*")
.splitAsStream(input)
.mapToDouble(Double::parseDouble)
.toArray();
EDIT
To also accept expressions such as x1 + x2, you can default to 1 when the string returned by split is empty (and amend the regex slightly):
String input = "Z = x1 + x2 + 6716x3";
input = input.replaceAll("^[^x\\d]+", "");
double[] numbers = Pattern.compile("x\\d+[^x\\d]*")
.splitAsStream(input)
.mapToDouble(s -> s.isEmpty() ? 1d : Double.parseDouble(s))
.toArray();
RE-EDIT
Add the missing 1 before the x manually:
String input = "Z = x1 + x2 + 6716x3 + x4";
input = input.replace(" x", " 1x")
.replaceAll("^[^x\\d]+", "");
double[] numbers = Pattern.compile("x\\d+[^x\\d]*")
.splitAsStream(input)
.mapToDouble(Double::parseDouble)
.toArray();
You could do the whole grabbing in a single regex (per row which I assume from your example what you're interested in) -
(?:=|\+)\s*(\d+)
It matches either a = or a +, skipping any spaces and then captures the number. Make it global and it'll capture the entire row. The result will be in the capture group array. (Don't speak java well enough to tell you exactly how from the top of my head).
Check it here at regex101. (Note - sample shows all the rows at once - you'd have to do them one by one.)
Since you pattern is a number followed by an x, using positive lookahead like this will work.
Regex: \d+(?=x)
Explanation:
(?=x) looks ahead and checks if x is present. If yes then \d+ is matched.
Regex101 Demo
Note: Use double escape \\d if necessary.
I've been working on the Blue Pelican Java project called Add 'Em Up for several hours now, and I can't figure out how to get it to work. The project description is this:
Consider the following program that allows something like 8 + 33 + 1,345 +137 to be entered as
String input from the keyboard. A Scanner object then uses the plus signs (and any adjoining
whitespace) as delimiters and produces the sum of these numbers(1523).
import java.io.*;
import java.util.*;
public class Tester
{
public static void main(String args[])
{
Scanner kb = new Scanner(System.in);
System.out.print("Enter something like 8 + 33 + 1,345 +137 : ");
String s = kb.nextLine( );
Scanner sc = new Scanner(s);
sc.useDelimiter("\\s*\\+\\s*");
int sum = 0;
while(sc.hasNextInt( ))
{
sum = sum + sc.nextInt( );
}
System.out.println("Sum is: " + sum);
}
}
The output will typically look like this:
Enter something like 8 + 33 + 1,345 +137 : 8 + 33 + 1,345 + 137
Sum is: 1523
Now modify this program so as to allow either plus or minus signs. Don’t forget to allow for a
leading plus or minus sign on the first number in the sequence. If the leading number has no sign,
assume the number is positive. Your output should typically appear as follows:
Enter something like 8 + 33 + 1,345 -137 : 8 + 33+ 1,345 -137
Sum is: 1249
The code below is what I currently have. The program works just fine for adding numbers, but for some reason the subtraction isn't working. For example, if you enter 5-2, the answer comes out as -7 instead of 3.
public class AddEmUp {
public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
System.out.print("Enter something like 8 + 33 + 1345 - 137 : ");
String s = kb.nextLine();
Scanner sc = new Scanner(s);
int sum = 0;
if (s.contains("+")) {
sc.useDelimiter("\\s*\\+\\s*");
while (sc.hasNextInt()) {
sum = sum + sc.nextInt();
}
}
if (s.contains("-")) {
sc.useDelimiter("\\s*\\-\\s*");
while (sc.hasNextInt()) {
sum = sum - sc.nextInt();
}
}
System.out.println("Sum is: " + sum);
}
Any help on what I should be trying to do in order to fix this would be much appreciated. Thanks!
The subtraction case is going to require a little more work than addition in this code! I think once you understand what is happening, you'll see how you need to adjust your strategy.
This is what is happening right now with the input 5 - 2.
int sum = 0
s.contains("-") is true.
sum = sum - sc.nextInt() occurs,
Remember at the top of your code sum was set to zero!
so sum = 0 - 5
Now sum = -5.
s.contains("-") is true.
sum = sum - sc.nextInt() occurs
sum = -5 - 2.
At the end of your program, sum = -7.
You are going to need to restructure the logic of your program a bit. Right now, the first thing you check is to see if there is either a '+' or a '-' symbol in your input. If there is a '+' symbol, you start from sum=0 and add every number you see. This works pretty well for addition, and you'll always get the right answer. If there is a '-' symbol, you start from sum=0 and subtract every number you see. That's not quite the intention with subtraction though. In the case of 5 - 2, what you would rather do is from sum=0 '+ 5' and then '- 3'.
Your code is fine in the sense that it compiles and runs - what you have here is what is known as a 'logic bug'. The steps that you have asked the program to do are not the same as the actual steps you want it to do. Give careful thought to what is happening at each point of your program to make sure that it behaves correctly.