-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRack.java
More file actions
executable file
·120 lines (108 loc) · 4.22 KB
/
Rack.java
File metadata and controls
executable file
·120 lines (108 loc) · 4.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.LinkedHashMap;
/**
* Represents a Rack of Scrabble tiles. This class models a rack of Scrabble tiles,
* supporting operations to compute subsets of tiles (multisets) and their multiplicities.
*/
public class Rack {
private String rack;
private String rackUnique;
private ArrayList<String> subSets;
private int[] multiplicity;
/**
* Constructs a `Rack` instance from a given input string.
*
* @param input the string representing the rack of tiles.
* It may contain duplicate characters.
*/
public Rack(String input) {
this.rack = input;
this.rackUnique = getUniqueChars(input);
this.multiplicity = getMultiplicity(input);
this.subSets = allSubsets(this.rackUnique, this.multiplicity, 0);
}
/**
* Extracts the unique characters from the input string while preserving their order.
*
* @param word the input string.
* @return a string of unique characters from the input.
*/
public static String getUniqueChars(String word) {
LinkedHashSet<Character> uniqueChars = new LinkedHashSet<>();
for (int i = 0; i < word.length(); i++) {
uniqueChars.add(word.charAt(i));
}
StringBuilder res = new StringBuilder();
for (Character curChar : uniqueChars) {
res.append(curChar);
}
return res.toString();
}
/**
* Computes the multiplicity of each unique character in the input string.
*
* @param word the input string.
* @return an array of integers representing the count of each unique character.
*/
public static int[] getMultiplicity(String word) {
LinkedHashMap<Character, Integer> characterCount = new LinkedHashMap<>();
for (int i = 0; i < word.length(); i++) {
Character curChar = word.charAt(i);
if (characterCount.containsKey(curChar)) {
Integer count = characterCount.get(curChar);
characterCount.put(curChar, count + 1);
} else {
characterCount.put(curChar, 1);
}
}
int[] result = new int[characterCount.size()];
int index = 0;
for (int count : characterCount.values()) {
result[index] = count;
index++;
}
return result;
}
/**
* Finds all subsets of the multiset starting at position k in unique and mult.
* unique and mult describe a multiset such that mult[i] is the multiplicity of
* the char
* unique.charAt(i).
* PRE: mult.length must be at least as big as unique.length()
* 0 <= k <= unique.length()
*
* @param unique a string of unique letters
* @param mult the multiplicity of each letter from unique.
* @param k the smallest index of unique and mult to consider.
* @return all subsets of the indicated multiset. Unlike the multiset in the
* parameters,
* each subset is represented as a String that can have repeated
* characters in it.
* @author Claire Bono
*/
private static ArrayList<String> allSubsets(String unique, int[] mult, int k) {
ArrayList<String> allCombos = new ArrayList<>();
if (k == unique.length()) { // multiset is empty
allCombos.add("");
return allCombos;
}
// get all subsets of the multiset without the first unique char
ArrayList<String> restCombos = allSubsets(unique, mult, k + 1);
// prepend all possible numbers of the first char (i.e., the one at position k)
// to the front of each string in restCombos. Suppose that char is 'a'...
String firstPart = ""; // in outer loop firstPart takes on the values: "", "a", "aa", ...
for (int n = 0; n <= mult[k]; n++) {
for (int i = 0; i < restCombos.size(); i++) { // for each of the subsets
// we found in the recursive call
// create and add a new string with n 'a's in front of that subset
allCombos.add(firstPart + restCombos.get(i));
}
firstPart += unique.charAt(k); // append another instance of 'a' to the first part
}
return allCombos;
}
public ArrayList<String> getAllSubsets() {
return this.subSets;
}
}