解一元一次方程的那些坑(记洛谷P1022题RE的经历)

important!!!

遇到RE不可怕,纯粹的RE还行(后面没有WA的话,可能你的算法本身没错)。
这固然会使得我们困惑,但我们只需要记得最常见的几种RE,加以分析,给一些脑洞大的测试样例就一般可以测出隐藏的语法Bug。。。

空指针还好吧,在OJ里的大问题不是空指针,一般是NumberFormatException或者越界的异常等等………………自己去测测,必有惊喜,必有福报~~

终于做了一个黄题,Nice!!!

题目要求

P1022题目链接

在这里插入图片描述
在这里插入图片描述

分析

其实就是拿过来一个一元一次方程然后求解。。。

问题是,坑是真多。。下面分享几个。。。。

  • 首先是你得处理符号,因为比如说“-”即是减号也是负号,“+”只代表加号(我们不会在正数前面加+)。
  • 接下来你要注意怎么去split到数据,如果你不想逐个处理,可以分治,先按照“=”切分为左右两部分字符串,然后左右分别按照“+”或者“-”切分。(正则为"[+]|[-]"
  • 然后你得注意开头的符号要消去,不要直接split导致出现"",这是糟糕的情况,会RE。(比如“-2x+2=3”)
  • 还有就是你得知道:-0.0000000000001这样的数在截出来以后是-0.000,这不能被OJ接收。。。
  • 接着上面一条说,另外非常恶心的是,-0.0/2得到的是-0.000(保留三位小数),这个-0.000其实按照我们补码理论是不存在的,它的存在就很恶心,在jshell里测试的时候就是与0.000相等的(包括与0相等)。其实一样,但你放OJ里就gg了,是不行的。。。
  • ……

第一次提交——WA+RE

这个WA的比较弱智,因为没注意输出格式。。。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String expression = scanner.nextLine();
        scanner.close();
        //未知变量的表示(小写字母)
        char x = 'x';
        for (char c : expression.toCharArray()) {
            if (c >= 'a' && c <= 'z') {
                x = c;
                break;
            }
        }
        String[] expressionArr = expression.split("=");
        boolean leftNeg = false, rightNeg = false;
        String left = expressionArr[0], right = expressionArr[1];
        if (left.startsWith("-")) {
            leftNeg = true;
            left = left.substring(1, left.length());
        }
        if (right.startsWith("-")) {
            rightNeg = true;
            right = right.substring(1, right.length());
        }
        Queue<Character> leftCharacters = new LinkedList<>();
        if (leftNeg) {
            leftCharacters.offer('-');
        } else {
            leftCharacters.offer('+');
        }
        for(char c : left.toCharArray()) {
            if (c == '+' || c == '-') {
                leftCharacters.offer(c);
            }
        }
        Queue<Character> rightCharacters = new LinkedList<>();
        if (rightNeg) {
            rightCharacters.offer('-');
        } else {
            rightCharacters.offer('+');
        }
        for(char c : right.toCharArray()) {
            if (c == '+' || c == '-') {
                rightCharacters.offer(c);
            }
        }
        String[] leftArr = left.split("[+]|[-]"), rightArr = right.split("[+]|[-]");
        int leftCounter = 0, leftCoefficient = 0, rightCounter = 0, rightCoefficient = 0;
        outer:
        for (String leftObj : leftArr) {
            char[] chars = leftObj.toCharArray();
            char sign = leftCharacters.poll();
            for (char c : chars) {
                if (c == x) {
                    leftObj = leftObj.substring(0, leftObj.length()-1);
                    leftCoefficient += Integer.parseInt(sign+leftObj);
                    continue outer;
                }
            }
            //不是未知量
            leftCounter += Integer.parseInt(sign+leftObj);
        }
        outer:
        for (String rightObj : rightArr) {
            char[] chars = rightObj.toCharArray();
            char sign = rightCharacters.poll();
            for (char c : chars) {
                if (c == x) {
                    rightObj = rightObj.substring(0, rightObj.length()-1);
                    rightCoefficient += Integer.parseInt(sign+rightObj);
                    continue outer;
                }
            }
            //不是未知量
            rightCounter += Integer.parseInt(sign+rightObj);
        }
        System.out.printf("%.3f", ((double)(rightCounter-leftCounter))/(leftCoefficient-rightCoefficient));
    }
}

在这里插入图片描述

第二次提交——RE

第二次RE了,平时测试没问题,但就很不解。。。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String expression = scanner.nextLine();
        scanner.close();
        //未知变量的表示(小写字母)
        char x = 'x';
        for (char c : expression.toCharArray()) {
            if (c >= 'a' && c <= 'z') {
                x = c;
                break;
            }
        }
        String[] expressionArr = expression.split("=");
        boolean leftNeg = false, rightNeg = false;
        String left = expressionArr[0], right = expressionArr[1];
        if (left.startsWith("-")) {
            leftNeg = true;
            left = left.substring(1, left.length());
        }
        if (right.startsWith("-")) {
            rightNeg = true;
            right = right.substring(1, right.length());
        }
        Queue<Character> leftCharacters = new LinkedList<>();
        if (leftNeg) {
            leftCharacters.offer('-');
        } else {
            leftCharacters.offer('+');
        }
        for(char c : left.toCharArray()) {
            if (c == '+' || c == '-') {
                leftCharacters.offer(c);
            }
        }
        Queue<Character> rightCharacters = new LinkedList<>();
        if (rightNeg) {
            rightCharacters.offer('-');
        } else {
            rightCharacters.offer('+');
        }
        for(char c : right.toCharArray()) {
            if (c == '+' || c == '-') {
                rightCharacters.offer(c);
            }
        }
        String[] leftArr = left.split("[+]|[-]"), rightArr = right.split("[+]|[-]");
        int leftCounter = 0, leftCoefficient = 0, rightCounter = 0, rightCoefficient = 0;
        outer:
        for (String leftObj : leftArr) {
            char[] chars = leftObj.toCharArray();
            char sign = leftCharacters.poll();
            for (char c : chars) {
                if (c == x) {
                    leftObj = leftObj.substring(0, leftObj.length()-1);
                    leftCoefficient += Integer.parseInt(sign+leftObj);
                    continue outer;
                }
            }
            //不是未知量
            leftCounter += Integer.parseInt(sign+leftObj);
        }
        outer:
        for (String rightObj : rightArr) {
            char[] chars = rightObj.toCharArray();
            char sign = rightCharacters.poll();
            for (char c : chars) {
                if (c == x) {
                    rightObj = rightObj.substring(0, rightObj.length()-1);
                    rightCoefficient += Integer.parseInt(sign+rightObj);
                    continue outer;
                }
            }
            //不是未知量
            rightCounter += Integer.parseInt(sign+rightObj);
        }
        System.out.print(x + "=");
        System.out.printf("%.3f", ((double)(rightCounter-leftCounter))/(leftCoefficient-rightCoefficient));
    }
}

在这里插入图片描述

自检过程

其实试了很多,都没问题,于是就开一个大数,,,

先是尝试了大数,被爆了NumberFormatException,如我所料,题没限制范围,就改为long保保险。。

但还是这样:所以就意识到一个巨大的思维差别:我们写的一元一次方程一般+x这样就OK,但我们的程序只能直接认识+1x,这就得我们再分出一种情况讨论。。。
在这里插入图片描述

然后继续,还是WA:
在这里插入图片描述

就是分析部分分析到的-0.000的问题,我们应该让它输出0.000,这就要求必须在上面操作。

偏偏这个数不是0.000(因为这是截出来的,我们在上面judge的是原数,所以是大于-0.0005而不能变成-0.001的数值,是负数,所以处理一下就OK)

第三次提交——RE(好一些了,就剩一个RE了)

这次纯属智障行为,因为左边改了,右边没改,这点一定要注意!!!

不要犯这种无脑错。。。

代码不放了,显得智障。。。

在这里插入图片描述

第四次提交——AC

写的比较冗长,不是很好。。也没抽出来函数,直接main到底、。。。。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String expression = scanner.nextLine();
        scanner.close();
        //未知变量的表示(小写字母)
        char x = 'x';
        for (char c : expression.toCharArray()) {
            if (c >= 'a' && c <= 'z') {
                x = c;
                break;
            }
        }
        String[] expressionArr = expression.split("=");
        boolean leftNeg = false, rightNeg = false;
        String left = expressionArr[0], right = expressionArr[1];
        if (left.startsWith("-")) {
            leftNeg = true;
            left = left.substring(1, left.length());
        }
        if (right.startsWith("-")) {
            rightNeg = true;
            right = right.substring(1, right.length());
        }
        Queue<Character> leftCharacters = new LinkedList<>();
        if (leftNeg) {
            leftCharacters.offer('-');
        } else {
            leftCharacters.offer('+');
        }
        for(char c : left.toCharArray()) {
            if (c == '+' || c == '-') {
                leftCharacters.offer(c);
            }
        }
        Queue<Character> rightCharacters = new LinkedList<>();
        if (rightNeg) {
            rightCharacters.offer('-');
        } else {
            rightCharacters.offer('+');
        }
        for(char c : right.toCharArray()) {
            if (c == '+' || c == '-') {
                rightCharacters.offer(c);
            }
        }
        String[] leftArr = left.split("[+]|[-]"), rightArr = right.split("[+]|[-]");
        long leftCounter = 0, leftCoefficient = 0, rightCounter = 0, rightCoefficient = 0;
        outer:
        for (String leftObj : leftArr) {
            char[] chars = leftObj.toCharArray();
            char sign = leftCharacters.poll();
            for (char c : chars) {
                if (c == x) {
                    leftObj = leftObj.substring(0, leftObj.length()-1);
                    if ("".equals(leftObj)) {
                        leftCoefficient++;
                    } else {
                        leftCoefficient += Long.parseLong(sign+leftObj);
                    }
                    continue outer;
                }
            }
            //不是未知量
            leftCounter += Long.parseLong(sign+leftObj);
        }
        outer:
        for (String rightObj : rightArr) {
            char[] chars = rightObj.toCharArray();
            char sign = rightCharacters.poll();
            for (char c : chars) {
                if (c == x) {
                    rightObj = rightObj.substring(0, rightObj.length()-1);
                    if ("".equals(rightObj)) {
                        rightCoefficient++;
                    } else {
                        rightCoefficient += Long.parseLong(sign+rightObj);
                    }
                    continue outer;
                }
            }
            //不是未知量
            rightCounter += Long.parseLong(sign+rightObj);
        }
        double result = ((double)(rightCounter-leftCounter))/(leftCoefficient-rightCoefficient);
        if (result > -0.0005 && result < 0) {
            System.out.printf("%c=%.3f", x, 0.000);
        } else {
            System.out.printf("%c=%.3f", x, result);
        }
    }
}

庆祝一下:
在这里插入图片描述

发布了351 篇原创文章 · 获赞 610 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_43896318/article/details/103722611
今日推荐