1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.example.demo;
21
22 import javax.swing.tree.DefaultMutableTreeNode;
23 import javax.swing.tree.TreeNode;
24 import java.io.Serializable;
25 import java.math.BigInteger;
26 import java.util.Enumeration;
27
28
29
30
31
32 public class CantorInterval extends DefaultMutableTreeNode {
33
34 private final Fraction begin;
35 private final Fraction end;
36 private boolean initialized;
37
38 public CantorInterval() {
39 begin = Fraction.ZERO;
40 end = Fraction.ONE;
41 }
42
43 private CantorInterval(final Fraction begin, final Fraction end) {
44 this.begin = begin;
45 this.end = end;
46 }
47
48
49 private void init() {
50 if (!initialized) {
51 initialized = true;
52 final Fraction subtract = end.subtract(begin);
53 final Fraction multiply = subtract.multiply(Fraction.ONE_THIRD);
54 final Fraction oneThird = multiply.add(begin);
55 add(new CantorInterval(begin, oneThird));
56
57 final Fraction twoThird = end.subtract(begin).multiply(Fraction.TWO_THIRDS).add(begin);
58 add(new CantorInterval(twoThird, end));
59 }
60 }
61
62 @Override
63 public int getChildCount() {
64 init();
65 return super.getChildCount();
66 }
67
68 @Override
69 public TreeNode getChildAt(final int i) {
70 init();
71 return super.getChildAt(i);
72 }
73
74 @Override
75 public Enumeration<TreeNode> children() {
76 init();
77 return super.children();
78 }
79
80 public String getLabel() {
81 return "[" + begin + ", " + end + "]";
82 }
83
84 public String toString() {
85 return getLabel();
86 }
87
88 public static final class Fraction implements Serializable {
89
90 private final BigInteger numerator;
91 private final BigInteger denominator;
92
93 public static final Fraction ZERO = new Fraction(0);
94 public static final Fraction ONE = new Fraction(1);
95 public static final BigInteger THREE = BigInteger.valueOf(3);
96 public static final Fraction ONE_THIRD = new Fraction(BigInteger.ONE, THREE);
97 public static final Fraction TWO_THIRDS = new Fraction(BigInteger.valueOf(2), THREE);
98
99 private Fraction(final long i) {
100 numerator = BigInteger.valueOf(i);
101 denominator = BigInteger.ONE;
102 }
103
104 private Fraction(final BigInteger numerator, final BigInteger denominator) {
105 BigInteger n = numerator;
106 BigInteger d = denominator;
107 while (n.remainder(THREE).equals(BigInteger.ZERO)
108 && d.remainder(THREE).equals(BigInteger.ZERO)) {
109 n = n.divide(THREE);
110 d = d.divide(THREE);
111 }
112 this.numerator = n;
113 this.denominator = d;
114 }
115
116 public Fraction add(final Fraction value) {
117 return new Fraction(
118 numerator.multiply(value.denominator).add(denominator.multiply(value.numerator)),
119 denominator.multiply(value.denominator));
120 }
121
122 public Fraction subtract(final Fraction value) {
123 return new Fraction(
124 numerator.multiply(value.denominator).subtract(denominator.multiply(value.numerator)),
125 denominator.multiply(value.denominator));
126 }
127
128 public Fraction multiply(final Fraction value) {
129 return new Fraction(
130 numerator.multiply(value.numerator),
131 denominator.multiply(value.denominator));
132 }
133
134 @Override
135 public String toString() {
136 final StringBuilder builder = new StringBuilder();
137 if (denominator.equals(BigInteger.ONE)) {
138 builder.append(numerator);
139 } else {
140 builder.append(numerator);
141 builder.append("/");
142 builder.append(denominator);
143 }
144 return builder.toString();
145 }
146 }
147 }