我正在尝试解决这个问题 - https://www.e-olymp.com/en/problems/7549但我无法通过所有测试(仅通过1/4)。我用这些输入测试了我的代码:
(AlC2)3Na4
3Al+6C+4Na
Gh(G2H3(H1A45)2)5(Bn6Mn3)5
450A+30Bn+10G+Gh+25H+15Mn
(Na1000)10Na02
10002Na
所以,看起来它有效,但它不起作用。任何提示都会很棒。
这是问题本身: 分子M的化学式描述了它的原子化学。化学式遵循以下语法:
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 |你L |你好
U:='A'| .. | 'Z'
L:='a'| .. | 'Z'
计数C表示其前面的子组S的乘数。例如,H2O有两个H(氢)和一个O(氧)原子,(AlC2)3Na4含有3个Al(铝),6个C(碳)和4个Na(钠)原子。
输入
包含多个测试用例。对于每个测试用例,将有一行包含有效的化学式。每行不超过100个字符。
输出
对于每一行,将有一行输出,即化学品的原子分解,如样本输出中所示。原子以字典顺序列出,隐含的计数为1,未明确写入。输出中没有空格。正确输出中的所有计数都可以用32位有符号整数表示。
这是我的代码(无论如何可能看起来很恶心):
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 :(得分:1)
您是否尝试过O1234
或private static boolean isCont(char c) {
return c >= 'a' && c <= 'z';
}
private static isNum(char c) {
return c >= '0' && c <= '9';
}
作为输入?两者似乎都被语法所允许?
c
要将单个数字字符Character.getNumericalValue(c)
转换为相应的值,您可以使用(c - '0')
- 或仅使用while (line.length() > i + 1 && isNum(line.charAt(i + 1))) {
atom.n = 10 * atom.n + (line.charAt(++i) - '0');
}
。 Character类javadoc可能包含更多有趣的用例提示......
<强> P.S。强> 我真的不明白为什么在有条件地添加 cont 字母后你不使用相同数字的解析代码....
让我抛出你可能会觉得有用的代码片段:
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 37.4419,
lng: -122.1419
},
zoom: 8
});
var line = new google.maps.Polyline({
path: [new google.maps.LatLng(37.4419, -122.1419), new google.maps.LatLng(37.4519, -122.1519)],
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 10,
geodesic: true,
map: map
});
// extend line from each end along its existing heading
// pick 20e6 meters as an arbitrary length
var lineHeading = google.maps.geometry.spherical.computeHeading(line.getPath().getAt(0), line.getPath().getAt(1));
var newPt0 = google.maps.geometry.spherical.computeOffset(line.getPath().getAt(0), 20000000, lineHeading);
line.getPath().insertAt(0, newPt0);
var newPt1 = google.maps.geometry.spherical.computeOffset(line.getPath().getAt(1), 20000000, lineHeading + 180);
line.getPath().push(newPt1);
}
google.maps.event.addDomListener(window, "load", initMap);