【问题标题】:How to detect different non-numerical input in Java?如何在 Java 中检测不同的非数字输入?
【发布时间】:2020-03-20 08:35:10
【问题描述】:

我正在尝试创建一个程序来计算以下形式的用户输入:分数、混合分数和小数。我对分数输入没有任何问题,我有的是混合分数和小数。

import java.util.Scanner;

public class Fraction {

    public static int gcd(int a, int b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }

    public static void main(String[] args) {

        Scanner scan = new Scanner(System.in);
        //ignore all non-numerical input
        //how to detect if that non-numerical input is '/' or '.', or ' ' (blank space)?
        scan.useDelimiter("\\D");

        int num, den;
        num = scan.nextInt();
        den = scan.nextInt();

        int GCD = gcd(num, den);
        num = num / GCD;
        den = den / GCD;

        if (den == 0) {
            System.out.println("Invalid denominator, cannot divide by 0");
        } else {
            System.out.println("Fraction: "+num+"/"+den);
            if (num > den) {
                System.out.println("Mixed Fraction: "+(num / den)+" "+(num % den)+"/"+den);
            } else {
                System.out.println("Mixed Fraction: N/A");
            }
            System.out.println("Decimal: "+((double) num / (double) den));
        }

        scan.close();

    }
}

现在,我只能输入分数,不能输入带分数或小数。以下是分数输入的正确输出示例:

Input:
46/22

Output:
Fraction: 23/11
Mixed Fraction: 2 1/11
Decimal: 2.090909090909091

我需要创建一个程序可以自动检测非数字输入是“/”、“”(空格)还是“.”的程序。区分分数、混合分数和小数。有什么办法可以做到吗?

注意:我对 Java 还很陌生,我学过的唯一其他语言是 C。

【问题讨论】:

  • 您应该将整行作为字符串读取,然后再进行处理。您可以简单地遍历所有字符并根据它决定输入的内容。
  • 在 C 中也是一样的......

标签: java java.util.scanner delimiter


【解决方案1】:

建议:

  • 阅读整行用户输入 (scanner.nextLine())
  • 使用正则表达式PatternMatcher)来检测它是哪种输入大小写(分数、混合分数、小数)。
  • 如果匹配,提取值使用捕获组
  • 如果没有匹配的情况,告诉用户输入格式无效

您需要的模式如下:

Pattern DECIMAL = Pattern.compile("\\s*(-?\\d+(?:\\.\\d+)?)\\s*");
Pattern FRACTION = Pattern.compile("\\s*(-?\\d+)\\s*\\/\\s*(\\d+)\\s*");
Pattern MIXED_FRACTION = Pattern.compile("\\s*(-?\\d+)\\s+(\\d+)\\s*\\/\\s*(\\d+)\\s*");

提示:这些模式也接受负值,例如 -3.14-5/8-2 1/3),并且对空格很宽容(-2 3 / 4-2 3/4 相同)。

匹配和提取值:

String line = scanner.nextLine();

Matcher matcher = DECIMAL.matcher(line);
if (matcher.matches()) {
    System.out.println("Decimal: " + matcher.group(1));
}
matcher = FRACTION.matcher(line);
if (matcher.matches()) {
    System.out.println("Fraction: " + matcher.group(1) + "/" + matcher.group(2));
}
matcher = MIXED_FRACTION.matcher(line);
if (matcher.matches()) {
    System.out.println("Mixed Fraction: " + matcher.group(1) + " " + matcher.group(2) + "/" + matcher.group(3));
}

提示:如果您不熟悉正则表达式,并且想了解它的每个部分的作用,或者您想构建和测试它们,可以使用许多有用的在线工具,例如regex101.com。将 Java 代码中的表达式粘贴到这些工具中时,请确保删除转义的反斜杠 (\\ -> \)。

【讨论】:

    【解决方案2】:

    如果您只想读取普通分数,您可以使用分隔符(例如 scan.useDelimiter("/"); ) 但是,如果您希望能够读取不同的输入,则必须使用字符串,如以下代码中的完整解决方案所示:

    import java.util.Scanner;
    
    public class Fraction {
    
        public static int gcd(int a, int b) {
            if (b == 0) {
                return a;
            }
            return gcd(b, a % b);
        }
    
        public static void main(String[] args) {
            boolean run = true;
            Scanner scan = new Scanner(System.in);
            scan.useDelimiter(System.lineSeparator());
            do {
                String input = scan.next();
                int num = 0, den = 0;
                if (input.matches("-?\\d*\\.\\d*")) {
                    // input is floating point number... convert it, may
                    // https://stackoverflow.com/a/26084714/12558456 fits better for you
                    String[] splittedinput = input.split("\\.");
                    num = Integer.parseInt(splittedinput[0] + splittedinput[1]);
                    den = (int) Math.pow(10, splittedinput[1].length());
    
                } else if (input.matches("-?\\d* \\d*/\\d*")) {
                    String[] splittedinput = input.split("/");
                    String[] splittedfront = splittedinput[0].split(" ");
                    den = Integer.parseInt(splittedinput[1]);
                    num = Integer.parseInt(splittedfront[0]) * den + Integer.parseInt(splittedfront[1]);
                } else if (input.matches("-?\\d*/\\d*")) {
                    String[] splittedinput = input.split("/");
                    num = Integer.parseInt(splittedinput[0]);
                    den = Integer.parseInt(splittedinput[1]);
                } else if (input.contentEquals("q")){
                    run=false;
                    System.out.println("quit programm");
                    continue;
                } else {
                    System.out.println("invalid input, plese type in Fraction, Decimal or Mixed Fraction");
                    continue;
                }
    
                int gcd = gcd(num, den);
                num = num / gcd;
                den = den / gcd;
    
                if (den == 0) {
                    System.out.println("Invalid denominator, cannot divide by 0");
                } else {
                    System.out.println("Fraction: " + num + "/" + den);
                    if (num > den) {
                        System.out.println("Mixed Fraction: " + (num / den) + " " + (num % den) + "/" + den);
                    } else {
                        System.out.println("Mixed Fraction: " + num);
                    }
                    System.out.println("Decimal: " + ((double) num / (double) den));
                }
            } while (run);
    
            scan.close();
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-10-26
      • 2012-09-22
      • 1970-01-01
      • 1970-01-01
      • 2017-08-24
      • 2014-08-16
      • 2012-02-02
      • 2015-02-17
      • 2011-04-17
      相关资源
      最近更新 更多