Reputation: 33
I'm fairly new to java programming, and i'm writing a "Complex" class so i can learn a bit about OOP.
While writing a read() method to get the user input on a Complex number, i ran into a problem. Currently, the user has to input 2 numbers separated by spaces, and those will be respectively the real and imaginary parts. But if they enter something like "3 + 4i" or "3.23+4.1i", either the whole thing is ignored or only the first number is read.
I want to make this method better by allowing the user to input the number in any of those formats, plus allowing them to simply enter something like "3i" instead of "0 + 3i".
What i found while researching usually involved patterns or Double.parseDouble, neither of which I got to work for my case.
My question is: How can i detect those characters so i can parse the complex number properly?
P.S: Here's the bit of my method that reads user input for now
if(userIn.hasNextDouble())
{
this.real=userIn.nextDouble();
}
if(userIn.hasNextDouble())
{
this.imag=userIn.nextDouble();
}
Upvotes: 3
Views: 5423
Reputation: 1742
Read a String
instead of a Double
. Then:
boolean firstPositive = true;
boolean secondPositive = true;
if (s.charAt(0) == '-') // See if first expr is negative
firstPositive = false;
if (s.substring(1).contains("-"))
secondPositive = false;
String[] split = s.split("[+-]");
if (split[0].equals("")) { // Handle expr beginning with `-`
split[0] = split[1];
split[1] = split[2];
}
double realPart = 0;
double imgPart = 0;
if (split[0].contains("i")) // Assumes input is not empty
imgPart = Double.parseDouble((firstPositive ? "+" : "-") + split[0].substring(0,split[0].length - 1));
else
realPart = Double.parseDouble((firstPositive ? "+" : "-") + split[0]);
if (split.length > 1) { // Parse second part of expr if it exists
if (split[1].contains("i"))
imgPart = Double.parseDouble((secondPositive ? "+" : "-") + split[1].substring(0,split[1].length - 1));
else
realPart = Double.parseDouble((secondPositive ? "+" : "-") + split[1]);
}
// Use realPart and imgPart ...
System.out.println(realPart + (imgPart < 0 ? "" : "+") + imgPart + "i");
If you only want to support Integer
s then change Double.parseDouble
to Integer.parseInt
.
It handles anything from 3
to -5.123i
to -5-631231.2123123i
Upvotes: 3
Reputation: 100279
I understand that it's a learning task and you want to implement it by yourself, but if other people will read this question it's much better to use Apache Commons Math library. It has a ComplexFormat
class which can parse complex numbers:
String str = "3.23+4.1i";
Complex c = new ComplexFormat().parse(str);
double realPart = c.getReal();
double imaginaryPart = c.getImaginary();
Upvotes: 0
Reputation: 1193
I took the liberty to do this. Just give it a try. It does not check for incorrect input. It will create the complex numbers, store them in an ArrayList and output the newly created numbers to the screen.
import java.util.ArrayList;
import java.util.Scanner;
public class Complex {
Double real=0d;
Double complex=0d;
Complex(Double real, Double complex){
this.real=real;
this.complex=complex;
}
Complex(){
}
public void setReal(Double real){
this.real=real;
}
public void setComplex(Double complex){
this.complex=complex;
}
public Double getReal(){
return real;
}
public String getComplex(){
return complex+"i";
}
public String toString(){
if (real==0d)
return complex+"i";
else if (complex==0d)
return real+"";
else
return real+" + "+complex+"i";
}
static ArrayList<Complex> complexList=new ArrayList<Complex>();
public static void createComplex(){
Scanner scanner=new Scanner(System.in);
System.out.println("Type the complex numbers; Type Done to finish!");
String x=scanner.next();
while (!x.equals("Done")){
// System.out.println(x);
Complex no=new Complex();
//check if the user has inputted only one number
if (!x.contains("+")&&!x.contains("i")){
no.setReal(Double.parseDouble(x));
x= scanner.next();
//ask for the second number; no wrong input checks
no.setComplex(Double.parseDouble(x));
}
//check if the user inputted something like 123.3i
else if (!x.contains("+")&&x.contains("i")){
//create the complex number; replace i with ""
x=x.replace("i","");
// System.out.println(x);
no.setComplex(Double.parseDouble(String.valueOf(x)));
}
else{
//else remove the + sign and create a complex number
//input like 123.3+32i
//no wrong input checks
x= x.replaceAll("\\s+","");
String[] tokens = x.split("\\+");
no.setReal(Double.parseDouble(String.valueOf(tokens[0])));
tokens[1]=tokens[1].replace("i","");
no.setComplex(Double.parseDouble(String.valueOf(tokens[1])));
}
//ask for next input until Done is typed
x=scanner.next();
complexList.add(no);
}
}
public static void main(String[] args) {
createComplex();
for (Complex x:complexList){
System.out.println(x.toString());
}
}
}
Test input & output:
Type the complex numbers; Type Done to finish!
123.123
412231.21
123i
9i
1+9i
123+12312.3i
Done
123.123 + 412231.21i
123.0i
9.0i
1.0 + 9.0i
123.0 + 12312.3i
Upvotes: 1
Reputation: 109
Idea for an algorithm easy to implement that might work :
- Read the line //ex: "3.23 + 4i" --- ex2: "3.23" --- ex3: "4i"
- Get rid of all spaces //ex: "3.23+4i" --- ex2: "3.23" --- ex3: "4i"
Split with "+" char //ex: ["3.23","4i"] --- ex2: ["3.23"] --- ex3: ["4i"]
4.1 If one element in array => find the result by just testing if it ends by "i" (fairly trivial)
4.2 If two element in the array =>
4.2.1 verify if the first element ends by i and read it accordingly (fairly trivial)
4.2.2 verify if the first element ends by i and read it accordingly (fairly trivial)
I think all step are relatively easy to implement, but if you have a question as to how to do it, don't hesitate. I suppose there are ways to do it more elegantly with patterns and so on, but sometime, the simplest things works too (if you don't have performance issues).
Godd luck,
Mathias
Upvotes: 1
Reputation: 719
In a first try do:
String test="3+4i";
String[] temp=null;
String realString=null;
String imagString=null;
if(test.contains("+")){
temp=test.split("\\+");
}
else if(test.contains("-")){
temp=test.split("-");
}
if(temp[0].contains("i")){
realString=temp[1];
imagString=temp[0].trim().split("i")[0];
}
else{
realString=temp[0];
imagString=temp[1].trim().split("i")[0];
}
System.out.println(realString+ " " +imagString);
It is just a first try to help you. You ll have to adapt it to accept numbers like "-3,14i + 12". And you'll still have to parse the string into the right format.
Upvotes: 0