简体   繁体   中英

Parsing a complex number in java

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?

PS: 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();
}

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

Idea for an algorithm easy to implement that might work :

  1. Read the line //ex: "3.23 + 4i" --- ex2: "3.23" --- ex3: "4i"
  2. Get rid of all spaces //ex: "3.23+4i" --- ex2: "3.23" --- ex3: "4i"
  3. 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

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

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.

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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM