2016-04-23 12 views
0

Ich versuche, dies zu lösen - https://www.e-olymp.com/en/problems/7549, aber ich kann nicht alle Tests bestehen (bestanden nur 1/4). Ich habe meinen Code mit diesen Eingaben getestet:Trennen Sie die Atome von der angegebenen chemischen Formel programmgesteuert

(AlC2)3Na4 
3Al+6C+4Na 

Gh(G2H3(H1A45)2)5(Bn6Mn3)5 
450A+30Bn+10G+Gh+25H+15Mn 

(Na1000)10Na02 
10002Na 

So, sieht aus wie es funktioniert, aber es funktioniert nicht. Jeder Hinweis wäre großartig.

Hier ist das Problem selbst: Die chemische Formel eines Moleküls M beschreibt sein atomares Make-up. Chemische Formeln folgen der folgenden Grammatik:

M: = G | M G

G: = S | S C

S: = A | '(' M ')'

C: = T | N E

E: = D | D E

T: = '2' | ... | '9'

N: = '1' | ... | '9'

D: = '0' | .. | '9'

A: = U | U L | U L L

U: = 'A' | .. | 'Z'

L: = 'a' | .. | 'z'

Der Zähler C repräsentiert einen Multiplikator für die ihm vorangehende Untergruppe S. Zum Beispiel hat H2O zwei H (Wasserstoff) und ein O (Sauerstoff) Atome, und (AlC2) 3Na4 enthält 3 Al (Aluminium), 6 C (Kohlenstoff) und 4 Na (Natrium) Atome.

Eingabe

Enthält mehrere Testfälle. Für jeden Testfall gibt es eine Zeile mit einer gültigen chemischen Formel. Jede Zeile hat nicht mehr als 100 Zeichen.

Output

Für jede Zeile gibt es eine Zeile ausgegeben werden, die in Form einer Summe die Atom Zersetzung der chemischen ist, wie in der Beispielausgabe gezeigt. Die Atome sind in lexikografischer Reihenfolge aufgelistet und eine Anzahl von 1 ist impliziert und nicht explizit geschrieben. In der Ausgabe sind keine Leerzeichen enthalten. Alle Zählungen in der richtigen Ausgabe können in vorzeichenbehafteten 32-Bit-Ganzzahlen dargestellt werden.

Und dies ist mein Code (es könnte widerlich aussieht, aber trotzdem):

import java.io.PrintWriter; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.Comparator; 
import java.util.Scanner; 
//Gh(G2H3(H1A45)2)5(Bn6Mn3)5 

public class Main { 

    static Scanner mIn; 
    static PrintWriter mOut; 

    public static void main(String[] args) { 
     mIn = new Scanner(System.in); 
     mOut = new PrintWriter(System.out); 

     String line = mIn.nextLine(); 

     ArrayList<Atom> atoms = new ArrayList<>(); 

     ArrayList<Integer> startBr = new ArrayList<>(); 
     for (int i = 0; i < line.length(); i++) { 
      if (line.charAt(i) == '(') { 
       //starting 
       startBr.add(atoms.size()); 
      } else if (line.charAt(i) == ')') { 
       //ending 
       int n = 1; 

       if (line.length() > i + 1 && isNum(line.charAt(i + 1))) { 
        n = line.charAt(i + 1) - '0'; 
        i++; 
        while (line.length() > i + 1 && isNum(line.charAt(i + 1))) { 
         n *= 10; 
         n += line.charAt(i + 1) - '0'; 
         i++; 
        } 
       } 

       for (int j = startBr.get(startBr.size() - 1); j < atoms.size(); j++) { 
        atoms.get(j).n *= n; 
       } 

       startBr.remove(startBr.size() - 1); 
      } else if (Character.isUpperCase(line.charAt(i))) { 
       Atom atom = new Atom(); 
       atom.name = String.valueOf(line.charAt(i)); 
       if (line.length() > i + 1 && isCont(line.charAt(i + 1))) { 
        atom.name += String.valueOf(line.charAt(i + 1)); 
        i++; 

        if (line.length() > i + 1 && isNum(line.charAt(i + 1))) { 
         atom.n = line.charAt(i + 1) - '0'; 
         i++; 

         while (line.length() > i + 1 && isNum(line.charAt(i + 1))) { 
          atom.n *= 10; 
          atom.n += line.charAt(i + 1) - '0'; 
          i++; 
         } 
        } 
       } 

       if (line.length() > i + 1 && isNum(line.charAt(i + 1))) { 
        atom.n = Integer.parseInt(String.valueOf(line.charAt(i + 1))); 
        i++; 
        while (line.length() > i + 1 && isNum(line.charAt(i + 1))) { 
         atom.n *= 10; 
         atom.n += line.charAt(i + 1) - '0'; 
         i++; 
        } 
       } 
       atoms.add(atom); 
      } 
     } 

     for (int i = 0; i < atoms.size(); i++) { 
      for (int j = i + 1; j < atoms.size(); j++) { 
       if (atoms.get(i).name.equals(atoms.get(j).name)) { 
        atoms.get(i).n += atoms.get(j).n; 
        atoms.get(j).n = -1; 
       } 
      } 
     } 

     for (int i = 0; i < atoms.size(); i++) { 
      if (atoms.get(i).n < 1) { 
       atoms.remove(i); 
      } 
     } 

     Collections.sort(atoms, ALPHABETICAL_ORDER); 

     for (int i = 0; i < atoms.size(); i++) { 
      p(atoms.get(i).toString()); 
      if (i != atoms.size() - 1) { 
       p("+"); 
      } 
     } 
    } 

    private static Comparator<Atom> ALPHABETICAL_ORDER = new Comparator<Atom>() { 
     public int compare(Atom atom1, Atom atom2) { 
      return atom1.name.compareTo(atom2.name); 
     } 
    }; 

    private static boolean isCont(char c) { 
     return c >= 'a' && c <= 'z'; 
    } 

    private static boolean isNum(char c) { 
     return c >= '0' && c <= '9'; 
    } 

    private static void p(Object obj) { 
     mOut.print(obj); 
     mOut.flush(); 
    } 

    private static class Atom { 
     public String name; 
     public int n = 1; 

     public String toString() { 
      if (n == 1) { 
       return name; 
      } 
      return n + name; 
     } 
    } 
} 
+0

Was ist ein Beispiel Eingabe und Ausgabe, wo es nicht funktioniert? –

+0

Ich gab 2 Tests als Beispiel und beide funktionieren. Es gibt verschiedene Tests auf e-olymp, aber ich kann sie nicht sehen. Problem ist, dass mein Code nur 1/4 Tests besteht. – sssemil

Antwort

1

Haben Sie versucht, Na123 oder O1234 als Input? Beide scheinen von der Grammatik erlaubt zu sein?

BTW: Einige der Methoden viel kürzer sein könnten ...

private static boolean isCont(char c) { 
    return c >= 'a' && c <= 'z'; 
} 

private static isNum(char c) { 
    return c >= '0' && c <= '9'; 
} 

Für ein einstelliges Zeichen c auf den entsprechenden Wert umzuwandeln, könnten Sie Character.getNumericalValue(c) verwenden - oder einfach nur (c - '0'). Die Zeichenklasse javadoc enthält wahrscheinlich mehr interessante Hinweise für Ihren Anwendungsfall ...

P.S. Ich verstehe nicht wirklich, warum Sie die gleiche Anzahl nicht-Code Parsen verwenden, nachdem die cont Brief bedingt Hinzufügen ....

mich in einem Codefragment werfen Lassen Sie nützlich finden könnten:

while (line.length() > i + 1 && isNum(line.charAt(i + 1))) { 
    atom.n = 10 * atom.n + (line.charAt(++i) - '0'); 
} 
+0

Danke für Ihre Antwort. Also, ich habe es bearbeitet und jetzt ist es gut mit (Na1000) 10Na02, die 10002Na gibt, aber immer noch 3/4 Tests fehlschlägt. – sssemil

+0

Ich habe kein anderes Problem entdeckt ... Ich würde versuchen, komplexere Beispiele zu generieren, bis Sie eine finden, die fehlschlägt, und dann versuchen, zu debuggen ,,, –