【问题标题】:Java fraction calculatorJava分数计算器
【发布时间】:2013-12-11 00:12:56
【问题描述】:

我真的是 Java 编程新手,我的 AP 计算机编程课程有一个作业要交,所以请耐心等待。我必须弄清楚如何将两个分数相乘。我想知道是否有任何方法可以在方法内声明一个变量并在该方法之外使用它(我在 intro 方法中的 while 循环)。谢谢,希望没有混淆!

import java.util.Scanner;
import java.util.StringTokenizer;

public class javatest3 {
    static int num1 = 0;
    static int num2 = 0;
    static int denom1 = 0;
    static int denom2 = 0;
    public static void main(String[] args){
    System.out.println("Enter an expression (or \"quit\"): "); //prompts user for input
    intro();

}
public static void intro(){
    Scanner input = new Scanner(System.in); 
    String user= input.nextLine();
    while (!user.equals("quit") & input.hasNextLine()){ //processes code when user input does not equal quit
        StringTokenizer chunks = new StringTokenizer(user, " "); //parses by white space
        String fraction1 = chunks.nextToken(); //first fraction
        String operand = chunks.nextToken(); //operator 
        String fraction2 = chunks.nextToken(); //second fraction
        System.out.println("Fraction 1: " + fraction1); 
        System.out.println("Operation: " + operand); 
        System.out.println("Fraction 2: " + fraction2); 
        System.out.println("Enter an expression (or \"quit\"): "); //prompts user for more input


    while (user.contains("*")){
        parse(fraction1);
        parse(fraction2);
        System.out.println("hi");
        int num = num1 * num2;
        int denom = denom1 * denom2;
        System.out.println(num + "/" + denom);
        user = input.next();

    }

    }
}

public static void parse(String fraction) {
    if (fraction.contains("_")){
        StringTokenizer mixed = new StringTokenizer(fraction, "_");
        int wholeNumber = Integer.parseInt(mixed.nextToken());
        System.out.println(wholeNumber);
        String frac = mixed.nextToken();
        System.out.println(frac);
        StringTokenizer parseFraction = new StringTokenizer(frac, "/"); //parses by forward slash
        int num = Integer.parseInt(parseFraction.nextToken());  
        System.out.println(num);
        int denom = Integer.parseInt(parseFraction.nextToken());
        System.out.println(denom);




    }
    else if (!fraction.contains("_") && fraction.contains("/")){
        StringTokenizer parseFraction = new StringTokenizer(fraction, "/"); //parses by forward slash
        int num = Integer.parseInt(parseFraction.nextToken());  
        System.out.println(num);
        int denom = Integer.parseInt(parseFraction.nextToken());
        System.out.println(denom);



    }else{ 
        StringTokenizer whiteSpace = new StringTokenizer(fraction, " "); 
        int num = Integer.parseInt(whiteSpace.nextToken());  
        System.out.println(num);
}

}}

【问题讨论】:

  • 不知道你在问什么——你想知道如何让 parse() 返回调用它的代码可以使用的分子和恶魔吗?
  • 方法内声明的变量被封装为局部变量,不能在方法外使用。
  • 也许创建一个 readFraction 方法,它接受fraction1 并返回一个(新类型:分数,带有分子和分母字段),然后您可以以一种理智的方式相乘

标签: java calculator


【解决方案1】:

这个简短的回答是“不”。其他人已经解释了原因......但这里有两种可能的选择。我不知道你是否已经学习了这些概念,但第一种选择与按引用传递与按值传递有关,第二种选择与面向对象编程有关。

备选方案#1:

你可以在方法外声明一个变量,将它传递给方法并使用它,然后该变量在方法外是可用的,因为它是在方法外声明的。我认为一个例子将有助于更清楚地说明这一点:

void foo () {
    Integer a = 1;
    Integer b = 2;
    bar(a,b);
    System.out.println("a = " + a + ", b = " + b);
}

void bar (Integer a, Integer b) {
    a = 4;
    b = 8;
}

结果应该是a = 4, b = 8。然而,非常重要要注意这是因为Integer(不像int)是一个类,所以它的对象是通过引用传递的。如果ab 只是ints,那么它们将按值传递。这意味着bar() 将拥有与foo() 分开的ab 的自己的副本,并且对bar() 中的变量的修改不会影响foo() 的副本。例如:

void foo () {
    int a = 1;
    int b = 2;
    bar(a,b);
    System.out.println("a = " + a + ", b = " + b);
}

void bar (int a, int b) {
    a = 4;
    b = 8;
}

这将产生结果a = 1, b = 2

我不太喜欢这种方法,因为它很丑而且很容易出错,但它可能的,而且如果操作正确,它会起作用。另外,如果您不编写面向对象的代码,您的选择可能是这个,或者只是不使用该部分的函数(这通常不是好的设计)。虽然这种事情在 C 和 C++ 等语言中更为常见。但是这些语言更明确地通过值或引用传递,并且您必须手动操作指针(而 Java 对程序员隐藏其指针),因此很难混淆何时通过值或引用传递某些东西(尽管更容易犯其他类型的错误)。

备选方案#2:

如果您可以选择的话,这将是我的偏好,但前提是您已经了解了一些面向对象编程的知识。如果您还没有了解这一点,我会采用另一种方法(但如果您感到好奇,请继续阅读)。

我会创建一个分数类,该类具有分子和分母的成员变量(如果需要支持的话,还有整数部分 - 尽管我个人会将整数部分的分数减少为分子和分母,无论如何,因为这就是我做数学的方式)。然后我会创建一个带有 String 参数的构造函数,该构造函数的主体将像您的 parse() 方法一样工作。所以这会让你做这样的事情......

String strFractionString = /* initialize the string, e.g., reading from input */
Fraction myFrac = new Fraction(strFractionString); // parses string and assigns num & denom
System.out.println("My Fraction: " + myFrac.numerator + "/" + myFrac.denominator);

【讨论】:

    【解决方案2】:

    不,变量的范围将限于您创建它的方法。 如果您想在该方法之外使用它,则必须在该方法之外声明该变量。

    这是variable scope 上的有用资源。

    【讨论】:

      【解决方案3】:

      假设您希望函数 parse() 同时返回一个分子和一个分母,有几种方法可以做到这一点。

      OO方式是定义一个有两个字段的类,一个分子和一个分母,并让parse()返回这个类型的一个实例

      class Fraction {
          public int Numerator = 0;
          public int Denominator = 1;
          public Fraction(int numerator, int denominator) {
              Numerator = numerator;
              Denominator = denominator;
          }
          public static Fraction parse(String fractionString) {
              int num, denom;
      
              // Your parse code (without the int num and int denom declarations) goes here.
      
              return new Fraction(num, denom);
          }
      }
      

      您的调用代码如下所示:

          Fraction f1, f2;
          f1= Fraction.parse(fraction1);
          f2= Fraction.parse(fraction2);
          int num = f1.Numerator * f2.Numerator;
          int denom = f1.Denominator * f2.Denominator;
      

      【讨论】:

        【解决方案4】:

        方法内声明的变量被封装为局部变量,不能在方法外使用。

        如果你想使用String frac,请执行此操作

        public class javatest3 {
            static String frac;
        
            public static void main(String[] args){
        
                // now you can use frac here
            }
        
            public static void parse(String fraction) {
                if (fraction.contains("_")){
                    ...
                    frac = mixed.nextToken();
                }
            }
        }
        

        【讨论】:

        • 我试过这个,如果我打印 frac 它将打印出 null,而不是分数。我检查了我的工作两次,但也许我做错了?
        • 您的逻辑可能有问题。还要确保所有变量都被初始化以避免 null
        【解决方案5】:

        只需在任何方法之外声明变量即可。确保并将变量设为静态。然后只需在方法中初始化。这样它就可以在该类中的任何方法中使用。这是您如何执行此操作的示例。

        package testPackage;
        
        public class Test {
            public static int waffle = 5;
        
            public static void main(String[] args) {
                method1();
                method2();
            }
        
            public static void method1() {
                System.out.println("Heyy Everyone");
                System.out.println("Waffle is " + waffle); // Print waffle before change
                waffle = waffle + 12 - 4; // Change waffle;
                System.out.println("Method 1 set waffle to " + waffle); // Print waffle after change after 
            }                                                           // change in method2
        
            public static void method2() {
                System.out.println("Waffle is " + waffle); // Print waffle in method2 after method1's change
                waffle = waffle * 3; // Change waffle
                System.out.println("Waffle is now set to " + waffle);// Print waffle/ after change in method2
            }
        }
        

        【讨论】:

        • 我认为在这种情况下这将是糟糕的编码风格。由于程序只有一个类,并且所有方法都是该类的成员,因此这基本上等同于(在语义上,尽管不是物理上)创建一个全局变量。 (另外,如果您打算这样做,则成员变量需要为 static 才能从静态方法访问。)
        • 那么声明变量,然后在方法内部设置它等于num、denom等?我试图这样做,但没有奏效。也许我做错了……
        【解决方案6】:

        您的原始代码打印并分隔分数和操作数。我们现在在 AP CS 中的作业要求我们将分数分成分子、操作数和恶魔。它看起来像这样。

        StringTokenizer st= new StringTokenizer (输入); 然后使用你的 find();

        中调用各个部分的方法

        【讨论】:

          【解决方案7】:

          这是我将分数相乘的代码。更简单,希望能回答你的问题。

          import java.io.BufferedReader;
          import java.io.IOException;
          import java.io.InputStreamReader;
          import java.util.Scanner;
          import java.util.StringTokenizer;
          
          public class javatest3
          {
              static int num1 = 0;
              static int num2 = 0;
              static int denom1 = 0;
              static int denom2 = 0;
          
              public static void main(String[] args)
              {
                  javatest3 javatest3 = new javatest3();
                  System.out.println("Enter an expression (or \"quit\"): "); // prompts
                                                                              // user for
                                                                              // input
                  BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
                  String[] array = null;
                  try {
                      array = in.readLine().trim().split(" ");
                      /*
                       * I get the array[0] and array[2], it because 2/3 * 3/4
                       * 2/3 is array[0], * is array[1] and 3/4 is array[2]
                       */
                      String[] arrayX = array[0].split("/");
                      String[] arrayY = array[2].split("/");
                      String result = javatest3.multiplyFaction(
                              Integer.valueOf(arrayX[0]), Integer.valueOf(arrayY[0]),
                              Integer.valueOf(arrayX[1]), Integer.valueOf(arrayY[1]));
          
                      System.out.println("Result: " + result);
                  }
                  catch (IOException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
          
                  // intro();
          
              }
          
              private String multiplyFaction(int x1, int y1, int x2, int y2)
              {
                  int mf1 = x1 * y1;
                  int mf2 = x2 * y2;
          
                  return String.valueOf(mf1) + "/" + String.valueOf(mf2);
              }
          
          //  public static void intro()
          //  {
          //      Scanner input = new Scanner(System.in);
          //      String user = input.nextLine();
          //      while (!user.equals("quit") & input.hasNextLine()) { // processes code
          //                                                              // when user
          //                                                              // input does
          //                                                              // not equal
          //                                                              // quit
          //          StringTokenizer chunks = new StringTokenizer(user, " "); // parses
          //                                                                      // by
          //                                                                      // white
          //                                                                      // space
          //          String fraction1 = chunks.nextToken(); // first fraction
          //          String operand = chunks.nextToken(); // operator
          //          String fraction2 = chunks.nextToken(); // second fraction
          //          System.out.println("Fraction 1: " + fraction1);
          //          System.out.println("Operation: " + operand);
          //          System.out.println("Fraction 2: " + fraction2);
          //          System.out.println("Enter an expression (or \"quit\"): "); // prompts
          //                                                                      // user
          //                                                                      // for
          //                                                                      // more
          //                                                                      // input
          //
          //          while (user.contains("*")) {
          //              parse(fraction1);
          //              parse(fraction2);
          //              System.out.println("hi");
          //              int num = num1 * num2;
          //              int denom = denom1 * denom2;
          //              System.out.println(num + "/" + denom);
          //              user = input.next();
          //
          //          }
          //
          //      }
          //  }
          
          //  public static void parse(String fraction)
          //  {
          //      if (fraction.contains("_")) {
          //          StringTokenizer mixed = new StringTokenizer(fraction, "_");
          //          int wholeNumber = Integer.parseInt(mixed.nextToken());
          //          System.out.println(wholeNumber);
          //          String frac = mixed.nextToken();
          //          System.out.println(frac);
          //          StringTokenizer parseFraction = new StringTokenizer(frac, "/"); // parses
          //                                                                          // by
          //                                                                          // forward
          //                                                                          // slash
          //          int num = Integer.parseInt(parseFraction.nextToken());
          //          System.out.println(num);
          //          int denom = Integer.parseInt(parseFraction.nextToken());
          //          System.out.println(denom);
          //
          //      }
          //      else if (!fraction.contains("_") && fraction.contains("/")) {
          //          StringTokenizer parseFraction = new StringTokenizer(fraction, "/"); // parses
          //                                                                              // by
          //                                                                              // forward
          //                                                                              // slash
          //          int num = Integer.parseInt(parseFraction.nextToken());
          //          System.out.println(num);
          //          int denom = Integer.parseInt(parseFraction.nextToken());
          //          System.out.println(denom);
          //
          //      }
          //      else {
          //          StringTokenizer whiteSpace = new StringTokenizer(fraction, " ");
          //          int num = Integer.parseInt(whiteSpace.nextToken());
          //          System.out.println(num);
          //      }
          //  }
          }
          

          【讨论】:

          • 这道题显然是课堂作业。 (OP对此很明确,他应该这样做。)请不要简单地为课堂作业/家庭作业/项目提供解决方案。允许 OP 复制粘贴解决方案并不能帮助他学习并鼓励作弊。 (对于this OP是否当然不会作弊发表任何评论!我假设不会。):) 此外,这违反了 SO w.r.t. 的政策。在家工作。相反,请帮助他理解他实际提出的问题的答案,并了解为什么会这样,但允许他编写自己的代码。
          • @DaveLillethun 对不起,我只是帮他写一些代码。但进一步他必须自己探索。
          • 我了解您正在努力提供帮助。但是,您实际上所做的是为分配提供一个完整的解决方案(尽我所能从 OP 中推断出分配是什么)。他可以从字面上复制粘贴您发布的内容并将其作为他自己的内容上交。 (我相信他不会,但关键是我们不应该提供诱惑。)虽然发布完整的解决方案对于 SO 上的一般性问题可能会有所帮助(而且通常是),但当涉及到课堂作业时,它实际上是有害的。此外,这违反了 SO 关于课堂作业问题的政策。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多