Как обнаружить разные нечисловые данные в Java? - PullRequest
2 голосов
/ 20 марта 2020

Я пытаюсь создать программу, которая будет вычислять пользовательский ввод в виде: дроби, смешанные дроби и десятичные дроби. У меня нет проблем с вводом дробей, у меня есть смешанные дроби и десятичные дроби.

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.

Ответы [ 2 ]

1 голос
/ 20 марта 2020

Предложение:

  • чтение всей строки ввода пользователя (scanner.nextLine())
  • использование регулярных выражений (Pattern и Matcher), чтобы определить, какой это входной регистр (дробь, смешанная дробь, десятичное число).
  • в случае совпадения извлечь значения с использованием групп захвата
  • если ни один из случаев не совпадает, сообщите пользователю, что формат ввода неверен .

Вам необходимы следующие шаблоны:

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 в эти инструменты.

enter image description here

0 голосов
/ 20 марта 2020

Если вы просто хотите читать только как обычную дробь, вы можете использовать разделитель (например, 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();

    }
}
...