简体   繁体   中英

for loop (remember where last to look) & Character.isDigit()

I have to do a project about the periodic table of elements. My dilemma is as follow. The user send you a molecular equation. It can be of any length. In this array there is Uppercase letters, Lowercase letters and numbers.

I also have an array of objects. Each object represents a element on the periodic table. Now I need to break this string the user send me up in smaller pieces - in pieces that is recognized by the array of objects. I also have to multiply the answer by either one or by the number right next to the last letter of the element.

I already tried the following. Make the string a char array. Run through the array from backwards - test for number ( Character.isDigit(a[i]); ), test for uppercase and lowercase... I always end up with the same problem. I have no idea how long the string will be. Lets say I find a number. Then if the previous char is an lowercase letter I need to do another check backwards for the uppercase letter. Then let's say I have the molecular equation and the amount I need to multiply it by - how do I let the computer know to start looking from the last uppercase letter.

I hope someone understand this!

Really in need of some help.

Another question: why come doesn't this code work:

String moleq = "HeKiLH2B6";

char[] a = moleq.toCharArray();
int g = moleq.length()-1;
int x = 1; //if not more than one of element - multiply getWeight by 1

int[][] indexofdigit = new int[moleq.length()][2];
int[] indexoflower = new int[moleq.length()];

for (int i = g; i <= 0; i--){

    if (Character.isDigit(a[i])) {
    String z = Character.toString(a[i]);
    x = Integer.parseInt(z);
    System.out.println("YES");

    }
}

This code never print me a Yes?

Your loop never executes as you are looking for i <= 0 condition. And it is not true at first, as g>0, if you change as i >= 0 it will work

For chemical formulas, maybe it would be interesting a regular expression (regexp). Something like ([AZ][az]?[0-9] )+. If I am not wrong( ) , this isolates an element and its cardinality (for example Fe2O3 --> group 1 (Fe2) + group 2 (O3)). Look at Pattern and Matcher for this.

  • If I am wrong, I am sure there is a regexp for formulas somewhere in Google. It usually is not language dependent (if it works for Perl it works for Java).

Note that with Java 5+ you can make that loop easier, using the for each loop:

for (char c : a){
  if (Character.isDigit(c)) {
    String z = Character.toString(c);
    x = Integer.parseInt(z);
    System.out.println("YES");
  }
}

To expand SJuan's suggestion:

String input = "HeKiLH2B6";
Pattern p = Pattern.compile("([A-Z][a-z]*)(\\d*)");    
Matcher m = p.matcher( input );

while(m.find()){
  String element = m.group( 1 );
  String cardinalityStr = m.group( 2 );
  int cardinality= 1;
  if( cardinalityStr != null && cardinalityStr .length() > 0)
  {
    cardinality= Integer.parseInt( cardinalityStr );
  }

  System.out.println( element + cardinality);
}

Yields:

He1
Ki1
L1
H2
B6

Edit: this would also work if the user entered something like He-Ki-L-H2-B6 or He Ki L H2 B6 .

The answer of SJuan76 in code (with the reluctant group qualifier added):

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {

    public static void main(String[] args) {
        // the compiled pattern can be re-used, are thread-safe 
        // and thus can be static final
        Pattern p = Pattern.compile("([A-Z][a-z]?[0-9]*)+?");

        // Per molecule (well, string) a matcher must be obtained.
        Matcher m = p.matcher("HeKiLH2B6");
        while(m.find()) {
            System.out.println(m.group());
        }
    }
}

This prints:

He
Ki
L
H2
B6

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