我对RationalSet
类的主要方法有疑问,这是RationalNode
的链接列表。在这个方法中,我创建了两个列表和两个节点,第一个列表有两个节点,但第二个只有一个,但是当我这个时,第二个有两个节点。我不知道为什么。
这是我的代码:
RationalSet
class RationalSet {
static Scanner keyboard = new Scanner(System.in).useLocale(Locale.US);
RationalNode first, previousIP, IP, previousAux;
int size;
public RationalSet() {
first = null;
previousIP = null;
IP = null;
size = 0;
}
public int cardinal() {
return size;
}
private boolean isEmpty() {
return first == null;
}
public boolean belongs(RationalNode r) {
return position(r) != null;
}
public void insert(RationalNode r) {
if (isEmpty()) {
first = r;
previousIP = first;
IP = previousIP.next;
size++;
} else if (!belongs(r)) {
previousIP.next = r;
previousIP = previousIP.next;
IP = previousIP.next;
size++;
}
}
public void delete(RationalNode r) {
if (!isEmpty()) {
RationalNode aux = position(r);
if (aux != null) {
if (aux == first)
first = aux.next; // I'm comparing references
else
previousAux.next = aux.next;
size--;
}
}
}
private RationalNode position(RationalNode r) {
RationalNode aux = first;
while (aux != null && !aux.equals(r)) {
previousAux = aux;
aux = aux.next;
}
return (aux == null) ? null : aux;
}
public boolean exists(RationalSet c) {
RationalNode aux = c.first;
while (aux != IP && belongs(aux))
aux = aux.next;
return aux == null;
}
public boolean equals(RationalSet c) {
if (c.cardinal() != cardinal())
return false;
if (this == c || (isEmpty() && c.isEmpty()))
return true;
return exists(c) && c.exists(this);
}
public String toString() {
String s = "{";
for (RationalNode aux = first; aux != null; aux = aux.next)
s += aux.toString() + ", ";
return s + "}";
}
public Object clone() {
RationalSet c = new RationalSet();
for (RationalNode aux = first; aux != null; aux = aux.next)
c.insert((RationalNode) aux.clone());
return (Object) c;
}
public RationalSet union(RationalSet c) {
RationalSet u = (RationalSet) this.clone();
for (RationalNode aux = c.first; aux != null; aux = aux.next)
u.insert(aux);
return u;
}
public RationalSet intersection(RationalSet c) {
RationalSet in = new RationalSet();
for (RationalNode aux = first; aux != null; aux = aux.next)
if (c.belongs(aux))
in.insert(aux);
return in;
}
public static void main(String[] args) {
RationalSet c1 = new RationalSet(),
c2 = new RationalSet();
Rational r1 = new Rational(-2, 3),
r2 = new Rational(1, 1);
RationalNode n1 = new RationalNode(r1),
n2 = new RationalNode(r2);
c1.insert(n1);
c1.insert(n2);
c2.insert(n1);
RationalSet u = c1.union(c2);
System.out.println(u);
System.out.println(c1.intersection(c2));
}
}
RationalNode
class RationalNode {
Rational rational;
RationalNode next;
public RationalNode(Rational r) {
rational = r;
next = null;
}
public RationalNode(Rational r, RationalNode s) {
rational = r;
next = s;
}
public boolean equals(Object obj) {
if (obj instanceof RationalNode) {
RationalNode a = (RationalNode) obj;
if (this == a)
return true;
return (rational == null) ? false : rational.equals(a.rational);
} else
return false;
}
public String toString() {
return rational.toString();
}
public Object clone() {
return (Object) new RationalNode((Rational) rational.clone());
}
}
理性
class Rational {
static Scanner keyboard = new Scanner(System.in).useLocale(Locale.US);
private long num, den;
public Rational(long n, long d) {
num = n;
den = d;
simplify();
}
Rational(Scanner t) {
System.out.print("Give me a numerator: ");
num = t.nextInt();
System.out.print("Give me a denominator: ");
den = t.nextInt();
simplify();
}
public static Rational read(Scanner input) {
System.out.print("Numerator: ");
long n = input.nextLong();
System.out.print("Denominator: ");
long d = input.nextLong();
return new Rational(n, d);
}
public long num() {
return num;
}
public long den() {
return den;
}
public Rational inverse() {
return new Rational(den, num);
}
public static Rational inverse(Rational r) {
return new Rational(r.den(), r.num);
}
public void autoInverse() {
long aux = num;
num = den;
den = aux;
}
public Rational opposite() {
return new Rational(-num, den);
}
public Rational multiply(Rational r) {
return new Rational(r.num * num, den * r.den);
}
public Rational divide(Rational r) {
return multiply(r.inverse());
}
public Rational sum(Rational r) {
return new Rational(num * r.den + den * r.num, den * r.den);
}
public Rational deduct(Rational r) {
return sum(r.opposite());
}
public void simplify() {
if (num == 0 && den != 0)
den = 1;
else if (num != 0 && den == 0)
num = (num >= 0) ? 1 : -1;
else if (num != 0 && den != 0) {
long numAbs = Math.abs(num), denAbs = Math.abs(den);
long lcd = lcd(numAbs, denAbs);
long signDen = den / denAbs;
num = signDen * (num / lcd);
den = signDen * (den / lcd);
}
}
private static long lcd(long a, long b) {
if (a == b)
return a;
else if (a > b)
return lcd(a - b, b);
else
return lcd(a, b - a);
}
public String toString() {
return num + "/" + den;
}
public boolean equals(Rational r) {
return r.num == num && r.den == den;
}
public Object clone() {
return (Object) new Rational(num, den);
}
public static void main(String a[]) {
Rational r1 = new Rational(23, -38), r2 = new Rational(4, 2);
System.out.println(r1.toString() + " " + r1.num + " / " + r1.den);
r1 = r1.inverse();
System.out.println(r1 + " " + r1.num + " / " + r1.den);
r1 = inverse(r1);
System.out.println(r1 + " " + r1.num + " / " + r1.den);
r1.autoInverse();
System.out.println(r1 + " " + r1.num + " / " + r1.den);
r1 = new Rational(23, -38);
Rational r3 = new Rational(23, -38);
System.out.println((r1 == r3) + " " + r1.equals(r3));
}
}
答案 0 :(得分:0)
您不应在set之外创建节点。当你这样做
c1.insert(n1);
首先执行此代码
if (isEmpty()) {
first = r;
previousIP = first;
IP = previousIP.next;
size++;
}
保存在first
和previousIP
当前节点中,该节点也由n1
存储。但是当你稍后执行时
c1.insert(n2);
因为c1
不再为空else
部分已执行
} else if (!belongs(r)) {
previousIP.next = r;
previousIP = previousIP.next;
IP = previousIP.next;
size++;
}
将previousIP.next
设置为r
,因为previous
与参考n1
和r
保持相同的对象为n2
,您实际上是在设置n1.next=n2
。
最后,您要使用
将n1
添加到第二套n2
c2.insert(n1);
但这意味着您要添加已在内部指向n1
的{{1}}。这就是n2
和c1
似乎包含相同结构的原因。
您应该做的是以内部创建自己的独立c2
的方式重写您的insert
方法。因此,您的代码不应该专注于接受RationalNodes
,而应关注RationalNodes
Rationals
您还需要重新设计处理public void insert(Rational r) {
if (isEmpty()) {
first = new RationalNode(r);//changed
previousIP = first;
IP = previousIP.next;
size++;
} else if (!belongs(r)) {
previousIP.next = new RationalNode(r);//changed
previousIP = previousIP.next;
IP = previousIP.next;
size++;
}
}
以处理RationalNode
的其余代码。
顺便说一句,你可以在Rational
中制作RationalNode
私人内部课程。这种方式更明确地说,该类的实例应仅由RationalSet
创建,并且必须属于其中一个实例。