0

I have a class called: ComplexNumber and I have a string that I need to convert into a ComplexNumber (Using Java).

If I have: "5+3i" or "6-2i", how do I appropriately parse these strings. I need to get it to 2 variables and I can do the rest.

String complexNum = "5+3i"; 

I would need to split the previous string into two double type variables double real = 5;
double imag = 3;

String complexNum = "6-2i";

I would need to split the previous string into two double type variables double real = 6; double imag = -2;

Can anyone give example code as to how they would go about doing this? There aren't any spaces to use as delimeters and I don't completely understand regular expressions (i've read a bunch of tutorials but it still doesn't click)


EDIT:

If regex is the best bet, i just have a hard time understanding how to create an appropriate expression.

I have the following code prepared:

String num = "5+2i";
String[] splitNum = num.split();

And i'm trying to figure out how to write the appropriate regex.

DMor
  • 770
  • 2
  • 8
  • 17

4 Answers4

6

Alternative 1

How about somewhat like this?

String complexNum = "5+3i"; 
String regex = "(\\d+)[+-](\\d+)i";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(complexNum);

if(matcher.find()){
   int real = Integer.parseInt(matcher.group(1));
   int imag = Integer.parseInt(matcher.group(2));
}

If you need to make the sign part of the number, then change the regular expression to

String regex = "(\\d+)([+-]\\d+)i"

This will make the sign part of the second matching group.

Alternative 2

Alternatively, if you are positively sure that the string is properly formatted and you do not care about the sing of the imaginary part, you could do something like this:

Scanner sc = new Scanner(complexNum).useDelimiter("[i+-]");
int real = sc.nextInt();
int imag = sc.nextInt();

Which is simpler.

Alternative 3

And if you're not sure of the format of the string, you can still use the regex to validate it:

if(complexNum.matches("(\\d+)[+-](\\d+)i")) {
  //scanner code here
} else {
   //throw exception or handle the case
}

Alternative 4

String[] tokens = complexNum.split("[i+-]");
int real = Integer.parseInt(tokens[0]);
int imag = Integer.parseInt(tokens[1]);
System.out.println(real +  " " + imag);
Edwin Dalorzo
  • 76,803
  • 25
  • 144
  • 205
  • very good answer, but why isn't this working: String[] s = complexNum.split((\\d+)[+-](\\d+)i); – DMor Jun 12 '12 at 06:05
  • @user1386498 The regular expression that you pass to your split method represent the tokens that you want to use to split your string. If you want to split it, use the same regex I used in the Scanner example. – Edwin Dalorzo Jun 12 '12 at 06:07
  • @user1386498 I just added your question as an alternative 4. – Edwin Dalorzo Jun 12 '12 at 06:09
  • 1
    the only problem, just noting is that it doesn't look at the sign in the expression. If it is 1-3i, real = 1; imag = -3; – DMor Jun 12 '12 at 06:18
  • And the sign of the `real` should also be considered. – maba Jun 12 '12 at 06:29
  • 1
    In that case use the first alternative, but change the regular expression to `"(\\d+)([+-]\\d+)i"` so that the sign is part of the second matching group. You cannot do the other alternatives then. – Edwin Dalorzo Jun 12 '12 at 06:32
4

Parsing complex number isn't that easy, because the real and img part could also contain a sign and an exponent. You could use apache-commons-math.

ComplexFormat cf = new ComplexFormat();
Complex c = cf.parse("1.110 + 2.222i");
stacker
  • 68,052
  • 28
  • 140
  • 210
0

Try this :

    String complexNum = "5+3i"; 
    int j = 0 ;
    String real = getNumber();
    j++;
    String imag = getNumber();   

public String getNumber()
{
      String num ;
      char c;
      int temp;
      for( ; j < complexNum.length() ; j++)
       {
           c = complexNum.charAt(j);
           temp = (int) c;
           if(temp > 57 ||temp < 48)
                 break;
           else
                  num += c;
       }
     return num;
}
Ravi Jain
  • 1,452
  • 2
  • 17
  • 41
0

Your regex should look something like this: (\\d+)([-+])(\\d+)i where \\d+ will match any number of digits, [+-] will match either a + or a -, and the i simply matches itself. The () are used to select out parts of the string that match.

Some code adapted from this link:

    // Compile the patten.
Pattern p = Pattern.compile("(\\d+)([-+])(\\d+)i");

// Match it.
Matcher m = p.matcher(string);

// Get all matches.
while (m.find() == true)
    System.out.println("Real part " + m.group(1) +
                 " sign " m.group(2) +
         " and imagionary part " + m.group(3));

Those will, of course, still be strings, so you will need to use something like

int real = Integer.parseInt(m.group(1))

to get the values into integer form, and you could use an if statement to fix the sign on the imaginary part, e.g.

if(m.group(2).equals("-"))
    imaginary *= -1;
    //if the value is positive, we don't have to multiply it by anything

UPDATE: Edwin Dalorzo's comment above simplifies this code. Use the regex "(\\d+)([+-]\\d+)i" to capture the sign of the imaginary part, and then no if statement is necessary.

kaz
  • 675
  • 2
  • 5
  • 13
  • I have m.group(3) is out of bounds and m.group(2) doesn't give me the sign. – DMor Jun 12 '12 at 06:22
  • Can you print the contents of each one? A simple `System.out.println(m.group(1))` should do it. It wouldn't hurt to post the code you're using too. – kaz Jun 12 '12 at 21:42