分数计算器与简化分数

问题描述 投票:-2回答:1

我的代码有几个问题,尽管我已经尝试过,但我还没有发现它有什么问题。这里是:

public class FracCalc {
    public static void main(String[] args) {
        // String to test
        //String input = "5_3/4 - 6_7/8 + 3/4";
        System.out.println(produceAnswer("-3_3/4 / -2_2/3"));
    }

    public static String produceAnswer(String input) {

        // Splits everything at every space
        String[] array = input.split(" ", 0);

        int allWholes = 0;
        int allNumerators = 0;
        int allDenominators = 1;

        // Multiplier is 1 or -1, 1 is add, -1 is subtract
        int multiplier = 1;
        // Operation mode; 0=+,-; 1=*; 2=/
        int mode = 0;

        // the for loop is used to identify and solve the the test
        for (int i = 0; i < array.length; i++) {
            String part = array[i];
            // 
            int whole = 0;
            int numerator = 0;
            int denominator = 0;

            // If it has a _, then it's a whole + fraction
            if (part.contains("_")) {

                // Convert Int from start of part (0) to the character before _, "55_30/40" -> 55

                whole = Integer.parseInt(part.substring(0, part.indexOf("_")));

                // Convert Int from the character AFTER _ to the character before /, "55_30/40" -> 30

                numerator = Integer.parseInt(part.substring(part.indexOf("_") + 1, part.indexOf("/")));

                // Convert Int from the character AFTER / to the end, "55_30/40" -> 40

                denominator = Integer.parseInt(part.substring(part.indexOf("/") + 1, part.length()));
            }
            // If no _, but still has a / AND it is not just the symbol "/", then it's just a fraction
            else if (part.contains("/") && part.length() != 1) {
                numerator = Integer.parseInt(part.substring(0, part.indexOf("/")));
                denominator = Integer.parseInt(part.substring(part.indexOf("/") + 1, part.length()));
            } //else if(part.contains("*") && part.contains("/")){}
            else if (part.contains("/") ) {
                mode = 2;
            }
            // TODO: Make multiplication

            // Negative sign(if number is negative)
            else if (part.contains("-")) {
                multiplier = -1;
            }
            // Positive sign(if number is positive)

            else if (part.contains("+")) {
                multiplier = 1;
            }
            // If neither _ nor /, then it's a whole
            else {
                whole = Integer.parseInt(part);
            }

            // Add all the wholes together
            allWholes += whole * multiplier;

            // If denom is the same
            if (denominator == allDenominators) {
                allNumerators += numerator * multiplier;
            }
            // If they're not the same
            else if (numerator != 0 && denominator != 0) {
                if (mode == 0 ) {
                    // Cross multiply
                    allNumerators *= denominator;

                    // Add
                    allNumerators += numerator * allDenominators * multiplier;


                    // Second part of cross multiply
                    allDenominators *= denominator;
                }
                // Multiplication
                else if (mode == 1) {

                    allDenominators *= denominator;

                    allNumerators *= numerator;

                }
                // Division
                else if (mode == 2) {
                    // Reverse multiply because (1/2)/(1/2) -> (1*1)/(2*2)
                    allNumerators = allNumerators * denominator;
                    allDenominators = allDenominators * numerator;
                }
            }
        }

        // Simplifies fraction by checking to see id the top is bigger than bottom
        // 9/4 -> 2_1/4


        while(allNumerators > allDenominators){
             allWholes = allNumerators / allDenominators;
             allNumerators %= allDenominators;
        }


        if (allWholes == 0) {
            return (allNumerators + "/" + allDenominators);
        }
        else if (allNumerators == 0 || allDenominators == 0) {
            return allWholes + "";
        }
        else {
            return allWholes + "_" + (allNumerators + "/" + allDenominators);
        }
    }
}

我的目标是使用简化的答案(作为分数)制作分数计算器。我很确定我的乘法,除法和简化while循环是问题所在。谢谢!

java arrays calculator
1个回答
0
投票

您的代码中有很多好的想法,但正如您所知,也存在问题。

  1. 在尝试跟踪计算中的整个部分时,您遇到了很多麻烦。与小学数学一样,通过以下方式使用整个部分来创建不正确的分数: numerator += whole*denominator; 然后用numeratordenominator进行数学计算,并在完成所有计算后提取整个部分,这是你已经在做的。
  2. 解析负数的方式是错误的。此外,你应该删除使用multiplier,只使用负numerator
  3. 如果你删除multiplier然后你需要跟踪-+作为单独的操作,但这很容易做到。
  4. 在每次计算结束时,您应该通过以下方式确保allDenominators为正: if (allDenominators < 0) { allNumerators = -allNumerators; allDenominators = -allDenominators; } 这将阻止您输出-3 / -4
  5. 简化分数的方法并不完全正确。你有: while(allNumerators > allDenominators){ allWholes = allNumerators / allDenominators; allNumerators %= allDenominators; } 如果allNumerators == allDenominators,即答案应该是1怎么办?此外,一旦你完成了allNumerators %= allDenominators,你的while循环中的条件就不再是真的了。只需这样做: if(allNumerators >= allDenominators){ allWholes = allNumerators / allDenominators; allNumerators %= allDenominators; }
  6. 最后考虑实施一个更大的公约数(GCD)例程来简化分数,例如:从48/1283/8

以下是您的代码的副本,其中包含了上述大部分内容,但您可能应该首先尝试自行修复它们,并仅将其用作参考。

public class FracCalc
{
  public static void main(String[] args)
  {
    // String to test
    System.out.println(produceAnswer("5_3/4 - 6_7/8 + 3/4"));
    System.out.println(produceAnswer("-3_3/4 / -2_2/3"));
  }

  public static String produceAnswer(String input)
  {
    // Splits everything at every space
    String[] array = input.split(" ", 0);

    int allNumerators = 0;
    int allDenominators = 1;

    // Operation mode; 0=+; 1=-; 2=*; 3=/
    int mode = 0;

    // the for loop is used to identify and solve the the test
    for (int i = 0; i < array.length; i++)
    {
      String part = array[i];

      int numerator = 0;
      int denominator = 0;

      // If it has a _, then it's a whole + fraction
      if (part.contains("_"))
      {
        // Convert Int from start of part (0) to the character before _,
        // "55_30/40" -> 55

        int whole = Integer.parseInt(part.substring(0, part.indexOf("_")));

        // Convert Int from the character AFTER _ to the character before /,
        // "55_30/40" -> 30

        numerator = Integer.parseInt(part.substring(part.indexOf("_") + 1, part.indexOf("/")));

        // Convert Int from the character AFTER / to the end, "55_30/40" -> 40

        denominator = Integer.parseInt(part.substring(part.indexOf("/") + 1, part.length()));

        if (whole > 0)
          numerator += whole * denominator;
        else
          numerator = -numerator + whole * denominator;
      }
      // If no _, but still has a / AND it is not just the symbol "/", then it's
      // just a fraction
      else if (part.contains("/") && part.length() != 1)
      {
        numerator = Integer.parseInt(part.substring(0, part.indexOf("/")));
        denominator = Integer.parseInt(part.substring(part.indexOf("/") + 1, part.length()));
      } // else if(part.contains("*") && part.contains("/")){}
      else if (part.equals("/"))
      {
        mode = 3;
      }
      else if (part.equals("+"))
      {
        mode = 0;
      }
      else if (part.equals("-"))
      {
        mode = 1;
      }
      else if (part.equals("*"))
      {
        mode = 2;
      }
      // If neither _ nor /, then it's a whole
      else
      {
        numerator = Integer.parseInt(part);
        denominator = 1;
      }

      if (numerator != 0 && denominator != 0)
      {
        if (mode < 2)
        {
          if (denominator == allDenominators)
          {
            allNumerators += numerator;
          }
          else
          {
            // Cross multiply
            allNumerators *= denominator;

            if (mode == 0)
            {
              // Add
              allNumerators += numerator * allDenominators;
            }
            else
            {
              // Sub
              allNumerators -= numerator * allDenominators;
            }

            // Second part of cross multiply
            allDenominators *= denominator;
          }
        }
        // Multiplication
        else if (mode == 2)
        {
          allDenominators *= denominator;
          allNumerators *= numerator;
        }
        // Division
        else if (mode == 3)
        {
          // Reverse multiply because (1/2)/(1/2) -> (1*1)/(2*2)
          allNumerators = allNumerators * denominator;
          allDenominators = allDenominators * numerator;
        }

        // make sure denominators are +ve
        if (allDenominators < 0)
        {
          allNumerators = -allNumerators;
          allDenominators = -allDenominators;
        }
      }
    }

    // Simplifies fraction by checking to see id the top is bigger than bottom
    // 9/4 -> 2_1/4

    int allWholes = 0;
    if (allNumerators >= allDenominators)
    {
      allWholes = allNumerators / allDenominators;
      allNumerators %= allDenominators;
    }

    // consider implementing GCD to reduce num/den to simplest form

    if (allWholes == 0)
    {
      return (allNumerators + "/" + allDenominators);
    }
    else if (allNumerators == 0 || allDenominators == 0)
    {
      return allWholes + "";
    }
    else
    {
      return allWholes + "_" + (allNumerators + "/" + allDenominators);
    }
  }
}

输出:

-48/128
1_13/32

我认为这是正确的答案。顺便说一下,Symbolab有一个很好的工具,让你输入表达式包含分数,这样你就可以检查你的结果。

© www.soinside.com 2019 - 2024. All rights reserved.