题目描述
ZL 先生首先研究了一些一元一次方程的实例:
- 4 + 3 x = 8 4+3x=8 4+3x=8。
- 6 a − 5 + 1 = 2 − 2 a 6a-5+1=2-2a 6a−5+1=2−2a。
- − 5 + 12 y = 0 -5+12y=0 −5+12y=0。
ZL 先生被主管告之,在计算器上键入的一个一元一次方程中,只包含整数、小写字母及
+
、-
、=
这三个数学符号(当然,符号“-
”既可作减号,也可作负号)。方程中并没有括号,也没有除号,方程中的字母表示未知数。
可认为键入的一元一次方程均为合法的,且有唯一实数解。输入格式
一个一元一次方程。
输出格式
解方程的结果(精确至小数点后三位)。
样例输入 #1
6a-5+1=2-2a
样例输出 #1
a=0.750
public static void solve() throws IOException {
List<String> list = new ArrayList<>();
String s = readString();
s = "+" + s;//加个符号,例如 2x = 4, 编程 +2x = +4,这样就知道 x的系数为正还是负,最后将 x的系数合并
s = s.replaceAll("\\+\\+", "+");//排除++的情况
s = s.replaceAll("\\+\\-", "-");//排除+-的情况
int idx = s.indexOf('=');
int sum = help(s, list, idx, 0, 1);//等号左边
s = s.substring(idx + 1);
s = "+" + s;
s = s.replaceAll("\\+\\+", "+");//排除++的情况
s = s.replaceAll("\\+\\-", "-");//排除+-的情况
sum = help(s, list, s.length(), sum, -1);//等号右边
sum = -sum;// 得到相反数,这样可以将已知数放等号右边,将未知数放等号左边如:2x=4
int sum2 = 0;// 计算未知数的系数
String a = "";
for (String t : list) {
t = t.replaceAll("\\-\\-", "+");
t = t.replaceAll("\\-\\+", "-");
t = t.replaceAll("\\+\\+", "+");
t = t.replaceAll("\\+\\-", "-");
int idx2 = 0;
for (int i = 0; i < t.length(); i++) {
if ((t.charAt(i) < '0' || t.charAt(i) > '9') && t.charAt(i) != '-' && t.charAt(i) != '+') {
idx2 = i;//得到系数
break;
}
}
a = t.substring(idx2);//未知字符
t = t.substring(0, idx2);//系数
if (t.length() == 1) {//出现 -x或者x的情况系数补充 -1或者1
t = t + "1";
sum2 += Integer.valueOf(t.substring(0, idx2 + 1));
continue;
}
sum2 += Integer.valueOf(t.substring(0, idx2));
}
double res = (double) (sum) / sum2;
if (res == 0) res = Math.abs(res);//可能出现-0.000的情况
printWriter.printf("%s=%.3f", a, res);
}
// idx用于确定枚举边界,sign用于判断字符串s位于等号左边还是右边
public static int help(String s, List<String> list, int idx, int sum, int sign) {
outer:
for (int i = 0; i < idx; i++) {
boolean flag = false;//用于判断是否有未知数,没有未知数的加到 sum中,有未知数的放到 list集合中
for (int j = i + 1; j < idx; j++) {//枚举到下一个加减号
char ch = s.charAt(j);
if (ch != '+' && ch != '-' && (ch < '0' || ch > '9')) flag = true;//出现了未知字符
if (ch == '+' || ch == '-') {//遇到了下一个加减号
if (!flag) {//未出现未知数
sum += Integer.valueOf(s.substring(i, j)) * sign;
} else {
if (sign == 1) {//等号左边
list.add(s.substring(i, j));
} else {//等号右边
list.add("-" + s.substring(i, j));
}
}
i = j - 1; break;//从正负号开始枚举
}
if (j == idx - 1) {//最后一个由正负号组成的数字
if (!flag) {
sum += Integer.valueOf(s.substring(i, idx)) * sign;
} else {
if (sign == 1) {
list.add(s.substring(i, idx));
} else {
list.add("-" + s.substring(i, idx));
}
}
break outer;
}
}
}
return sum;
}
好像没什么考点,纯模拟,注意一下正负号,以及未知数的系数为一或者负一的特殊情况,还有就是等号式子开头可能自带正号或者不带符号,遇到这种情况可以再加一个正号,然后通过replaceAll()
方法变为只有一个正号