问题描述
因此,我正在为我的OOP类编写一个作业,要求用户输入多个分数,然后随机生成该分数。部分作业指出,如果无法简化分数之一,则跳过它并创建一个可以简化的新分数。但是,不可还原的馏分仍能通过。如果分数的GCD为1,我需要一种方法让程序创建一个新分数。
代码:
import java.util.Random;
// The class is called Boxes because I'm supposed to print Boxes around the fractions,but I'll
implement it later.
class SimpleFracBoxes{
private int numberOfFractions = 0;
private String result = "";
Random myRandom = new Random( );
int min = 1;
int max = 100000;
public SimpleFracBoxes( )
{
}
public SimpleFracBoxes(int nOFracs)
{
numberOfFractions = nOFracs;
}
// makes the fractions
public void makeTheFractions()
{
for (int i = 0; i < numberOfFractions; i++)
{
Fraction frac = getAGoodFraction();
Fraction frac2 = frac.simplify();
result = result + " "+ (int)(i + 1) + ": " + frac + " simplifies to "+ frac2 + "\n" ;
}
}
// creates a fraction that can be divided
private Fraction getAGoodFraction()
{
Fraction frac;
do {
frac = new Fraction (myRandom.nextInt(max-min),myRandom.nextInt(max-min));
}
while (frac.getNumerator() >= frac.getDenominator());
int num = frac.getNumerator();
int denom = frac.getDenominator();
int gcd = frac.gcd(num,denom);
if (gcd == 1) {
getAGoodFraction();
} else if (gcd !=1) {
frac.simplify();
}
return frac;
}
public String getFractions()
{
return result;
}
}
分数类代码
public class Fraction{
private int numerator;
private int denominator;
public Fraction(){
this(0,1);
}
public Fraction(int number) {
this(number,1);
}
public Fraction(Fraction frac) {
this(frac.getNumerator(),frac.getDenominator());
}
public Fraction(int num,int denom){
setNumerator(num);
setDenominator(denom);
}
public static int gcd(int m,int n) {
int r = n % m;
while (r != 0) {
n = m;
m = r;
r = n % m;
}
return m;
}
public static Fraction min(Fraction f1,Fraction f2) {
double f1_dec = f1.decimal();
double f2_dec = f2.decimal();
if (f1_dec <= f2_dec) {
return f1;
} else {
return f2;
}
}
public Fraction add(Fraction frac) {
int a,b,c,d;
Fraction sum;
a = this.getNumerator();
b = this.getDenominator();
c = frac.getNumerator();
d = frac.getDenominator();
sum = new Fraction(a*d + b*c,b*d);
return sum;
}
public Fraction add(int number) {
Fraction frac = new Fraction(number,1);
Fraction sum = add(frac);
return sum;
}
public Fraction divide(Fraction frac) {
int a,d;
Fraction quotient;
a = this.getNumerator();
b = this.getDenominator();
c = frac.getNumerator();
d = frac.getDenominator();
quotient = new Fraction(a*d,b*c);
return quotient;
}
public Fraction divide(int number) {
Fraction frac = new Fraction(number,1);
Fraction quotient = divide(frac);
return quotient;
}
public boolean equals(Fraction frac) {
Fraction f1 = simplify();
Fraction f2 = frac.simplify();
if (f1.getNumerator() == f2.getNumerator() &&
f1.getDenominator() == f2.getDenominator()) {
return true;
} else {
return false;
}
}
public int getDenominator() {
return denominator;
}
public int getNumerator(){
return numerator;
}
public Fraction multiply(Fraction frac){
int a,d;
Fraction product;
a = this.getNumerator();
b = this.getDenominator();
c = frac.getNumerator();
d = frac.getDenominator();
product = new Fraction(a*c,b*d);
return product;
}
public Fraction multiply(int number){
Fraction frac = new Fraction(number,1);
Fraction product = multiply(frac);
return product;
}
public void setDenominator(int denom){
if (denom == 0) {
System.err.println("Fatal error");
System.exit(1);
}
denominator = denom;
}
public void setNumerator(int num) {
numerator = num;
}
public Fraction simplify(){
int num = getNumerator();
int denom = getDenominator();
int gcd = gcd(num,denom);
Fraction simp = new Fraction(num/gcd,denom/gcd);
return simp;
}
public Fraction subtract(Fraction frac) {
int a,d;
Fraction diff;
a = this.getNumerator();
b = this.getDenominator();
c = frac.getNumerator();
d = frac.getDenominator();
diff = new Fraction(a*d - b*c,b*d);
return diff;
}
public Fraction subtract(int number) {
Fraction frac = new Fraction(number,1);
Fraction difference = subtract(frac);
return difference;
}
public String toString() {
return getNumerator() + "/" + getDenominator();
}
private double decimal() {
return (double) getNumerator() / getDenominator();
}
}
Output:
How many fractions? 3
1: 28181/38503 simplifies to 28181/38503 // Unsimplified
2: 75654/99570 simplifies to 12609/16595
3: 787/31255 simplifies to 787/31255 // Unsimplified
解决方法
听起来您需要分数比较功能。
// returns true if two fractions are identical
public boolean identical(Fraction frac) ...
然后您可以编写一个if语句
if (!frac.identical(frac.reduce())) {
... print fraction ...
}
此外,我会考虑将分数缩减逻辑移至分数中,因为这样将来可以在不复制逻辑的情况下对其进行重用。通过在“分数的用户”中使用它,您将获得一个“数据结构”,其中“相关逻辑”在其他位置。一类的最基本定义是“逻辑紧密相关的数据”,其减少的分数与分数非常相关,而与将分数存储在数据库中并没有那么紧密的联系。
,- 类
decimal()
中的方法Fraction
未使用,因此我将其删除。 - 当GCD值为1时,不要递归调用方法
getAGoodFraction()
,而要使用循环。 - 使用方法
Fraction
和setNumerator()
,而不是每次随机生成的分子大于随机生成的分母时都创建一个新的setDenominator()
对象。那就是他们的目的。 - 无需在方法
simplify()
中调用方法getAGoodFraction()
。只需返回分数。因为GCD不等于1,所以您知道它可以简化。
将以下代码与您的代码进行比较。
请注意,我在类main()
中添加了Fraction
方法,以便能够运行代码。另外,由于来自{KevinAnderson的问题,comment,我还更改了方法gcd()
。
import java.util.Random;
public class Fraction {
private int numerator;
private int denominator;
public Fraction() {
this(0,1);
}
public Fraction(int number) {
this(number,1);
}
public Fraction(Fraction frac) {
this(frac.getNumerator(),frac.getDenominator());
}
public Fraction(int num,int denom) {
setNumerator(num);
setDenominator(denom);
}
public static int gcd(int m,int n) {
int factor = m;
int r = n % factor;
while (r != 0 && factor > 1) {
r = n % --factor;
if (r == 0) {
r = m % factor;
}
}
return factor;
}
public int getDenominator() {
return denominator;
}
public int getNumerator() {
return numerator;
}
public void setDenominator(int denom) {
if (denom == 0) {
System.err.println("Fatal Error");
System.exit(1);
}
denominator = denom;
}
public void setNumerator(int num) {
numerator = num;
}
public Fraction simplify() {
int num = getNumerator();
int denom = getDenominator();
int gcd = gcd(num,denom);
Fraction simp = new Fraction(num / gcd,denom / gcd);
return simp;
}
public String toString() {
return getNumerator() + "/" + getDenominator();
}
public static void main(String[] args) {
SimpleFracBoxes sfb = new SimpleFracBoxes(10);
sfb.makeTheFractions();
System.out.println(sfb.getFractions());
}
}
class SimpleFracBoxes {
private int numberOfFractions = 0;
private String result = "";
Random myRandom = new Random();
int min = 1;
int max = 100000;
public SimpleFracBoxes() {
}
public SimpleFracBoxes(int nOFracs) {
numberOfFractions = nOFracs;
}
//makes the fractions
public void makeTheFractions() {
for (int i = 0; i < numberOfFractions; i++) {
Fraction frac = getAGoodFraction();
Fraction frac2 = frac.simplify();
result += String.format("%" + String.valueOf(numberOfFractions).length() + "d. %5d/%5d simplifies to %5d/%5d%n",(i + 1),frac.getNumerator(),frac.getDenominator(),frac2.getNumerator(),frac2.getDenominator());
}
}
// creates a fraction that can be divided
private Fraction getAGoodFraction() {
int gcd = 1;
Fraction frac = new Fraction();
while (gcd == 1) {
do {
frac.setNumerator(myRandom.nextInt(max - min));
frac.setDenominator(myRandom.nextInt(max - min));
} while (frac.getNumerator() >= frac.getDenominator());
int num = frac.getNumerator();
int denom = frac.getDenominator();
gcd = Fraction.gcd(num,denom);
}
return frac;
}
public String getFractions() {
return result;
}
}
这是运行上述代码时产生的示例输出。
1. 64480/84728 simplifies to 8060/10591
2. 33376/79317 simplifies to 4768/11331
3. 50944/97026 simplifies to 25472/48513
4. 21339/45510 simplifies to 7113/15170
5. 35884/38628 simplifies to 8971/ 9657
6. 15148/17199 simplifies to 2164/ 2457
7. 72670/95005 simplifies to 14534/19001
8. 19810/44730 simplifies to 283/ 639
9. 61790/63956 simplifies to 30895/31978
10. 4824/ 5352 simplifies to 201/ 223