I have a Jave class that calculates all possible combination for a given array of elements and to do this it uses a recursive method.
It work fine but when the number of input elements raises I found out of memory problem.
What I'd like to do is calculate combinations in chuncks of a given size.
My problem is that I don't know how save and than restore the state for the recursive method,
specially when it the calling depth is high.
Beolw is the code.
Thanks a lot.
package uty;
import java.io.FileOutputStream;
import java.util.ArrayList;
public class ESCalcCombination {
int iMax = 0;
boolean bEnd = false;
int iLenInp;
ArrayList<Integer[]> resultList;
public ESCalcCombination(int[] inElements, int inMaxElem, int inMaxElemLen) {
if (inMaxElem > 0) {
iMax = inMaxElem;
} else {
iMax = new Double(Math.pow(2d, new Integer(inElements.length).doubleValue())).intValue();
}
resultList = new ArrayList(iMax);
iLenInp = inElements.length;
for (int i = 1; i <= iLenInp; i++) {
if (inMaxElemLen > 0) {
if (i > inMaxElemLen) {
break;
}
}
for (int j = 0; j < iLenInp; j++) {
if ((iLenInp - j) < i) {
break;
}
addNextElement(inElements, j, i, null);
if (bEnd) {
break;
}
}
if (bEnd) {
break;
}
}
}
private void addNextElement(int[] inElements, int inCurIndex, int inLimitLen, ArrayList<Integer> inCurrentCombination) {
if (inCurrentCombination != null
&& (inCurrentCombination.size() + (iLenInp - inCurIndex)) < inLimitLen) {
return;
}
ArrayList<Integer> alCombinationLoc = new ArrayList();
if (inCurrentCombination != null) {
alCombinationLoc.addAll(inCurrentCombination);
}
alCombinationLoc.add(inElements[inCurIndex]);
if (alCombinationLoc.size() == inLimitLen) {
Integer[] arComb = new Integer[alCombinationLoc.size()];
arComb = alCombinationLoc.toArray(arComb);
resultList.add(arComb);
alCombinationLoc.clear();
alCombinationLoc = null;
if (resultList.size() == iMax) {
bEnd = true;
}
return;
}
for (int i = ++inCurIndex; i < iLenInp; i++) {
addNextElement(inElements, i, inLimitLen, alCombinationLoc);
if (bEnd) {
return;
}
}
}
public void close() {
ESUty.closeAL(resultList);
}
public ArrayList<Integer[]> getCombinations() {
return resultList;
}
public static void main(String[] args) {
ESCalcCombination ESCaCo = new ESCalcCombination(new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, 0, 15);
FileOutputStream fos = null;
try {
fos = new FileOutputStream("c:\\test\\conbinations.txt");
for (int i = 0; i < ESCaCo.getCombinations().size(); i++) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < ESCaCo.getCombinations().get(i).length; j++) {
sb.append(ESCaCo.getCombinations().get(i)[j]);
}
System.out.println("elemento " + i + " = " + sb.toString());
fos.write((sb.toString() + System.getProperty("line.separator")).getBytes());
}
} catch (Exception ex) {
System.out.println("errore " + ex);
} finally {
ESUty.closeFileOutputStream(fos);
}
System.exit(0);
}
}
With recursion, part of the data is on stack, and stack cannot be saved that easily. If such functionality is required, rewrite everything using while loop together with the Stack or ArrayDeque data structure instead. This allows to save and restore the state without problems.
Related
can someone help me implement the maximum weight independent set for a TREE (not a graph)?
The tree is represented by an adjacency matrix, and we have an array for the weights of the vertices.
BFS output: // 0: distances from start vertex
// 1: BFS-order
// 2: parent-IDs
I tried this code, it doesn't work on all test cases and it says most of the time that the weight is too small.
Can someone help me find the errors?
import java.io.*;
import java.util.*;
public class Lab5
{
/**
* Problem: Find a maximum weight independent set using dynammic programming.
*/
private static int[] problem(Tree t, int[] weights)
{
// Implement me!
//base cases
if (t.noOfVertices==0) {
return new int[] {};
}
if (t.noOfVertices==1) {
return new int[] {weights[0]};
}
//we will implement this using bfs, we will use 0 as the root
int[][] bfs = t.bfs(0);
//finding leaves
int leaf[] = new int [t.noOfVertices];
//now we can implement our algorithm
//M is the maximum weight of the tree if it contains i, and M1 is the maximum weight of the tree if it doesn't contain i
int M[]=new int[t.noOfVertices];
int M1[]=new int[t.noOfVertices];
//treating elements that aren't leaves
int nodeDiscovered[] = new int[t.noOfVertices];
for (int i = 0; i<t.noOfVertices; i++) {
if (t.edges[i].length==1) {
leaf[i]=1;
M[i]=weights[i];
nodeDiscovered[i]=1;
M1[i]=0;
}
else {
leaf[i]=0;
nodeDiscovered[i]=0;
}
}
for (int i = 1; i<t.noOfVertices; i++) {
if (leaf[i]==1) {
int node = bfs[2][i];
if (nodeDiscovered[node]!=0) {
continue;
}
while (node>-1) {
int parent = bfs[2][node];
ArrayList<Integer> sibs = new ArrayList<Integer>();
if (parent!=-1) {
for (int j = 0; j<t.edges[parent].length; j++) {
if (t.edges[parent][j]!=bfs[2][parent]) {
sibs.add(t.edges[parent][j]);
}
}
}
else {
sibs.add(node);
}
for (int sib : sibs) {
if (nodeDiscovered[sib]!=0) {
continue;
}
M[sib]=weights[sib];
for (int k : t.edges[sib]) {
if(bfs[0][sib]==bfs[0][k]-1) {
M[sib]=M[sib]+M1[k];
M1[sib]+=(M[k]>M1[k])?M[k]:M1[k];
}
}
nodeDiscovered[sib]=1;
}
node = bfs[2][node];
}
}
}
//putting the answers in an arraylist
ArrayList<Integer> set = new ArrayList<Integer>();
if (M[0]>M1[0]) {
set.add(0);
}
for (int i = 1; i<t.noOfVertices; i++) {
if (!set.contains(bfs[2][i]) && M[i]>=M1[i] ) {
set.add(i);
}
}
System.out.println(set);
//putting the elements of the arraylist into an array of int
int[] set1 = new int[set.size()];
for (int i = 0; i<set.size(); i++) {
set1[i]=set.get(i);
}
return set1;
}
// ---------------------------------------------------------------------
// Do not change any of the code below!
// Do not change any of the code below!
/**
* Determines if a given set of vertices is an independent set for the given tree.
*/
private static boolean isIndSet(Tree t, int[] set)
{
if (set == null) return false;
boolean[] covered = new boolean[t.noOfVertices];
for (int i = 0; i < set.length; i++)
{
int vId = set[i];
int[] neighs = t.edges[vId];
if (covered[vId]) return false;
covered[vId] = true;
for (int j = 0; j < neighs.length; j++)
{
int nId = neighs[j];
covered[nId] = true;
}
}
return true;
}
private static final int LabNo = 5;
private static final String course = "CS 427";
private static final String quarter = "Fall 2021";
private static final Random rng = new Random(190817);
private static boolean testProblem(int[][] testCase)
{
int[] parents = testCase[0];
int[] weights = testCase[1];
Tree t = Tree.fromParents(parents);
int[] solution = maxIsWeight(t, weights);
int isWeight = solution[0];
int isSize = solution[1];
int[] answer = problem(t, weights.clone());
if (!isIndSet(t, answer))
{
System.out.println("Not an independent set.");
return false;
}
int ansWeight = 0;
for (int i = 0; i < answer.length; i++)
{
ansWeight += weights[answer[i]];
}
if (ansWeight < isWeight)
{
System.out.println("Weight too small.");
return false;
}
if (answer.length < isSize)
{
System.out.println("Set too small.");
return false;
}
return true;
}
private static int[] maxIsWeight(Tree t, int[] weigh)
{
int n = t.noOfVertices;
int[][] dfs = t.dfs(0);
int[] post = dfs[2];
int[] w = new int[n];
for (int i = 0; i < n; i++)
{
w[i] = weigh[i] * n + 1;
}
boolean[] isCandidate = new boolean[n];
for (int i = 0; i < n; i++)
{
int vId = post[i];
if (w[vId] <= 0) continue;
isCandidate[vId] = true;
int[] neighs = t.edges[vId];
for (int j = 0; j < neighs.length; j++)
{
int uId = neighs[j];
w[uId] = Math.max(w[uId] - w[vId], 0);
}
}
int isWeight = 0;
int isSize = 0;
for (int i = n - 1; i >= 0; i--)
{
int vId = post[i];
if (!isCandidate[vId]) continue;
isWeight += weigh[vId];
isSize++;
int[] neighs = t.edges[vId];
for (int j = 0; j < neighs.length; j++)
{
int uId = neighs[j];
isCandidate[uId] = false;
}
}
return new int[] { isWeight, isSize };
}
public static void main(String args[])
{
System.out.println(course + " -- " + quarter + " -- Lab " + LabNo);
int noOfTests = 300;
boolean passedAll = true;
System.out.println("-- -- -- -- --");
System.out.println(noOfTests + " random test cases.");
for (int i = 1; i <= noOfTests; i++)
{
boolean passed = false;
boolean exce = false;
try
{
int[][] testCase = createProblem(i);
passed = testProblem(testCase);
}
catch (Exception ex)
{
passed = false;
exce = true;
ex.printStackTrace();
}
if (!passed)
{
System.out.println("Test " + i + " failed!" + (exce ? " (Exception)" : ""));
passedAll = false;
//break;
}
}
if (passedAll)
{
System.out.println("All test passed.");
}
}
private static int[][] createProblem(int testNo)
{
int size = rng.nextInt(Math.min(testNo, 5000)) + 5;
// -- Generate tree. ---
int[] parents = new int[size];
parents[0] = -1;
for (int i = 1; i < parents.length; i++)
{
parents[i] = rng.nextInt(i);
}
// -- Generate weights. ---
int[] weights = new int[size];
for (int i = 0; i < weights.length; i++)
{
weights[i] = rng.nextInt(256);
}
return new int[][] { parents, weights };
}
}
I attached an image that contains the algorithm that I used.
I have to find a missing element from the array where array has got values from <0, N>.
For example: int tablica[] = {0, 1, 2, 3, 5};, missing number is 4.
I have got 3 implementations of this code, but...
Only one gives me output, why?
Why naiveFindMissing() and optimalFindMissing() don't give any output?
public class Zad2_Selftraining {
public static void main(String[] args) {
findMissing();
naiveFindMissing();
optimalFindMissing();
}
public static void findMissing() {
int tablica[] = {0, 1, 2, 3, 5};
for(int i = 0; i<tablica.length;i++ ){
if (tablica[i] != i){
System.out.println("Missing: " + i);
return;
}
}
System.out.println("Everything is correct");
return;
}
private static int naiveFindMissing() {
int array[] = {0,1,2,4,5,6,7};
int missing = 0;
boolean elementFound;
for (int elementToFind = 0; elementToFind <= array.length; elementToFind++) {
elementFound = false;
for (int elementInArray : array) {
if (elementToFind == elementInArray) {
elementFound = true;
break;
}
}
if (!elementFound) {
missing = elementToFind;
break;
}
}
return missing;
}
private static int optimalFindMissing() {
int array[] = {0,1,2,4,5,6,7};
int expectedSum = (array.length + 1) * array.length / 2;
int actualSum = 0;
for (int element : array) {
actualSum += element;
}
return expectedSum - actualSum;
}
}
Because you have System.out.println statement only in first method. The other two methods just return result without printing it
I have inside a simple Graph class this Dijkstra Algorithm O(n^2) implementation and when debugging it the output is different than the expected one from the JUnit Test and I cannot find the problem:
public void Dijkstra(T departureNode) {
initDijkstra(departureNode);
ArrayList<GraphNode<T>> V_S = fillWithoutElement(departureNode);
while (V_S.size() > 0) {
int w = chooseMinimum(D);
nodes.get(w).setVisited(true);
GraphNode<T> auxW = nodes.get(w);
V_S.remove(findOnV_S(V_S, auxW));
for(GraphNode<T> m : V_S) {
if (D[w] + weights[w][getNode(m.getElement())] < D[getNode(m.getElement())]) {
D[getNode(m.getElement())] = D[w] + weights[w][getNode(m.getElement())];
PD[getNode(m.getElement())] = w;
}
}
}
}
This is the auxiliary method chooseMinimum():
private int chooseMinimum(double[] auxD) {
int res = 0;
double min = INFINITE;
for (int i = 0; i < auxD.length; i++) {
if (!nodes.get(i).isVisited()) {
if (auxD[i] < min) {
min = auxD[i];
res = i;
}
}
}
return res;
}
And this is the findOnV_S() method:
private int findOnV_S(ArrayList<GraphNode<T>> V_S, GraphNode<T> auxW) {
int res = 0;
for(int i = 0; i < V_S.size(); i++) {
if(V_S.get(i).equals(auxW))
res = i;
}
return res;
}
This is the initDijkstra() method:
public void initDijkstra(T departureNode) {
if (!itExists(departureNode))
throw new IllegalArgumentException("Node does not exist");
D = new double[size];
PD = new int[size];
int j = getNode(departureNode);
// Initialize D
for (int i = 0; i < size; i++) {
if (edges[j][i]) {
D[i] = weights[j][i];
} else
D[i] = INFINITE;
}
// Initialize PD
for (int i = 0; i < size; i++) {
if (edges[j][i])
PD[i] = getNode(departureNode);
else
PD[i] = EMPTY;
}
initializeVisitedToFalseExceptStart(departureNode);
}
And this is the initializeVisitedToFalseExceptStart aux method:
private void initializeVisitedToFalseExceptStart(T departureNode) {
if (!itExists(departureNode))
throw new RuntimeException("Invalid node");
GraphNode<T> element = null;
for (int i = 0; i < size; i++) {
element = nodes.get(i);
if ((element.getElement()).equals(departureNode))
element.setVisited(true);
else
nodes.get(i).setVisited(false);
}
}
PD: I think that the wrong method is chooseMinimum()
PD2: In the next JUnit you will see that getD() will return a 2 dimensional array but the actual D inside the Graph class is a unidimensional array.
PD3: This is the simple JUnit test:
try
{
g.addNode("V1");
g.addNode("V2");
g.addNode("V3");
g.addNode("V4");
g.addNode("V5");
g.addNode("V6");
}
catch (Exception e)
{
System.out.println ("No repeated nodes are allowed" + e);
}
try
{
g.addEdge ("V1", "V2", 3.0);
g.addEdge ("V1", "V3", 4.0);
g.addEdge ("V1", "V5", 8.0);
g.addEdge ("V2", "V5", 5.0);
g.addEdge ("V3", "V5", 3.0);
g.addEdge ("V5", "V6", 3.0);
g.addEdge ("V5", "V4", 7.0);
g.addEdge ("V6", "V4", 2.0);
}
catch (Exception e)
{
System.out.println ("Starting or arrival node does not exists" + e);
}
g.Dijkstra ("V1");
assertArrayEquals (new double[][]{{Graph.INFINITE, 3.0, 4.0, 12.0, 7.0, 10.0}}, g.getD());
assertArrayEquals (new int[]{-1, 0, 0, 5, 2, 4}, g.getPD());
I think I found the problem. You have this method called initializeVisitedToFalseExceptStart(departureNode)
inside your initDijkstra method. So when the initial call to chooseMinimum is done in the while loop, you are finding the minimum without considering the departureNode
I think if you will remove that method call inside the initDijkstra method, your algorithm will run fine.
I am working on a cube solver at the moment and it uses breadth first search to find the shortest solution to the 2x2x2 rubiks cube solver. The thing is that in the search there are duplicate positions that get hit and my goal is to know how many of them I have and "prune" them out later.(I know how to avoid the duplicates but that is irrelevant to this post). Here is what it should look like
That is from an old version of the code which works with the hashCode and equals but I am trying to get the new version to work with it. I think the reason is because in the old version I override equals and hashCode, but in the new one I can't seem to do that because I am no longer comparing objects, rather arrays (that is guess). The current version isn't picking up duplicates due to this. It says there are no duplicates but that is incorrect.
here is what the hashCode and equals is like for the old version which detects duplicates.
private Cube() {
cube = new int[][] {
{ 0, 0, 0, 0 },
{ 1, 1, 1, 1 },
{ 2, 2, 2, 2 },
{ 3, 3, 3, 3 },
{ 4, 4, 4, 4 },
{ 5, 5, 5, 5 }
};
cube = scanCube(cube);
cube = print_cube(cube);
}
private Cube(Cube other) {
cube = new int[other.cube.length][];
for (int i = 0; i < other.cube.length; i++) {
cube[i] = Arrays.copyOf(other.cube[i], other.cube[i].length);
}
}
public boolean isSolved() {
for (int i = 0; i < cube.length; i++) {
for (int k = 1; k < cube[i].length; k++) {
if (cube[i][0] != cube[i][k]) {
return false;
}
}
}
return true;
}
#Override
public boolean equals(Object other) {
return other instanceof Cube && Arrays.deepEquals(((Cube) other).cube, cube);
}
#Override
public int hashCode() {
return Arrays.deepHashCode(cube);
}`
Here is the current version.
public static void main(String[] args) {
int[][] cube = new int[][] {
{ 0, 0, 0, 0 },
{ 1, 1, 1, 1 },
{ 2, 2, 2, 2 },
{ 3, 3, 3, 3 },
{ 4, 4, 4, 4 },
{ 5, 5, 5, 5 }
};
cube = scanCube(cube);
cube = print_cube(cube);
solve(cube);
}
private static boolean isSolved(int [][] cube) {
for (int i = 0; i < cube.length; i++) {
for (int k = 1; k < cube[i].length; k++) {
if (cube[i][0] != cube[i][k]) {
return false;
}
}
}
return true;
}
public static int[][] copyCube(int [][] cube){
int [][] copy = new int [6][4];
for(int i = 0; i < 6; i++ ){
copy[i] = cube[i].clone();
}
return copy;
}
public static boolean equals(int[][] other, int[][] cube) {
return Arrays.deepEquals(other, cube);
}
public int hashCode(int [][] cube) {
return Arrays.deepHashCode(cube);
}
In the search method is where duplicates are determined. Here is the code for the old one.
static public void solve(Cube c) {
Set<Cube> cubesFound = new HashSet<Cube>();
cubesFound.add(c);
Stack<Cube> s = new Stack<Cube>();
s.push(c);
Set<Stack<Cube>> initialPaths = new HashSet<Stack<Cube>>();
initialPaths.add(s);
solve(initialPaths, cubesFound);
}
static public void solve(Set<Stack<Cube>> livePaths, Set<Cube> cubesFoundSoFar) {
System.out.println("livePaths size:" + livePaths.size());
int numDupes = 0;
Set<Stack<Cube>> newLivePaths = new HashSet<Stack<Cube>>();
for (Stack<Cube> currentPath : livePaths) {
Set<Cube> nextStates = currentPath.peek().getNextStates();
for (Cube next : nextStates) {
if (currentPath.size() > 1 && next.isSolved()) {
currentPath.push(next);
System.out.println("Path length:" + currentPath.size());
System.out.println("Path:" + currentPath);
System.exit(0);
} else if (!cubesFoundSoFar.contains(next)) {
Stack<Cube> newCurrentPath = new Stack<Cube>();
newCurrentPath.addAll(currentPath);
newCurrentPath.push(next);
newLivePaths.add(newCurrentPath);
cubesFoundSoFar.add(next);
} else {
numDupes += 1;
}
}
}
System.out.println("Duplicates found " + numDupes + ".");
solve(newLivePaths, cubesFoundSoFar);
}
And the new one.
static private void solve(int[][] cube) {
int[][][] s = new int[12][6][4];
s[0] = cube;
Set<int[][][]> initialPaths = new HashSet<int[][][]>();
initialPaths.add(s);
Set<int[][]> cubesFound = new HashSet<int[][]>();
cubesFound.add(cube);
solve(initialPaths, cubesFound, 1);
}
static private void solve(Set<int[][][]> livePaths,Set<int[][]> cubesFoundSoFar, int iterationCount) {
System.out.println("livePaths size:" + livePaths.size());
Set<int[][][]> newLivePaths = new HashSet<int[][][]>();
int counter = 0;
int recordDepth = 0;
int duplicates = 0;
for(int[][][] currentPath : livePaths) {
Set<int [][]> nextStates = getNextStates(currentPath[iterationCount-1]);
for (int[][] next : nextStates) {
if (isSolved(next)) {
currentPath[iterationCount] = next;
int maxSteps = -1;
System.out.println("Path:" );
for(int i = 0; i < currentPath.length; i++) {
if(currentPath[i] != null) {
maxSteps = i;
System.out.println(toString(currentPath[i]));
}else {
break;
}
}
System.out.println("Path length:" + maxSteps);
System.exit(0);
} else if(!cubesFoundSoFar.contains(next)){
int[][][] newCurrentPath = new int[12][6][4];
newCurrentPath = currentPath.clone();
newCurrentPath[iterationCount] = next;
newLivePaths.add(newCurrentPath);
counter ++;
cubesFoundSoFar.add(next);
} else {
duplicates += 1;
}
}
}
//System.out.println(" Set.size(): "+newLivePaths.size());
String storeStates = "positions.txt";
try {
PrintWriter outputStream = new PrintWriter(storeStates);
outputStream.println(storeStates);
for(int[][][] s:newLivePaths) {
outputStream.println(toString(s[iterationCount]));
}
outputStream.close();
} catch (FileNotFoundException e) {
System.err.println("Fatal: could not open cache file for cube positions. exiting.");
e.printStackTrace();
System.exit(1);
}
System.out.println("Duplicates found "+ duplicates + ".");
solve(newLivePaths, cubesFoundSoFar, iterationCount+1);
}
You have not overridden the equals(Object) method in your second code, but
Set.contains(Object) use equals to compare the elements. Since there is none in Cube, the one of Object is used. This does not compare content, it just test if the objects are the same instance (same memory location).
Here the relevant part of contains:
... More formally, returns true if and only if this set contains an element e such that (o==null ? e==null : o.equals(e)). ...
You could add something like to the second code:
#Override
public boolean equals(Object other) {
if (other instanceof Cube)
return equals(cube, ((Cube) other).cube);
else
return false;
}
#Override
public int hashCode() {
return hashCode(cube);
}
Write a method to return the Toy that occurs in the list most frequent and another method to sort the toys by count.
This is my code
import java.util.ArrayList;
public class ToyStore {
private ArrayList<Toy> toyList;
public ToyStore() {
}
public void loadToys(String toys) {
toyList = new ArrayList<Toy>();
for (String item : toys.split(" ")) {
Toy t = getThatToy(item);
if (t == null) {
toyList.add(new Toy(item));
} else {
t.setCount(t.getCount() + 1);
}
}
}
public Toy getThatToy(String nm) {
for (Toy item : toyList) {
if (item.getName().equals(nm)) {
return item;
}
}
return null;
}
public String getMostFrequentToy() {
int position = 0;
int maximum = Integer.MIN_VALUE;
for (int i = toyList.size() - 1; i >= 0; i--) {
if (toyList.get(i).getCount() > maximum)
maximum = toyList.get(i).getCount();
position = i;
}
return toyList.get(position).getName();
}
public void sortToysByCount() {
ArrayList<Toy> t = new ArrayList<Toy>();
int count = 0;
int size = toyList.size();
for (int i = size; i > 0; i--) {
t.add(new Toy(getMostFrequentToy()));
t.get(count).setCount(getThatToy(getMostFrequentToy()).getCount());
toyList.remove(getThatToy(getMostFrequentToy()));
count++;
}
toyList = t;
}
public String toString() {
return toyList + "" + "\n" + "max == " + getMostFrequentToy();
}
}
Here is the method I care about
public void sortToysByCount() {
ArrayList<Toy> t = new ArrayList<Toy>();
int count = 0;
int size = toyList.size();
for (int i = size; i > 0; i--) {
t.add(new Toy(getMostFrequentToy()));
t.get(count).setCount(getThatToy(getMostFrequentToy()).getCount());
toyList.remove(getThatToy(getMostFrequentToy()));
count++;
}
toyList = t;
}
Here is my output
[sorry 4, bat 1, train 2, teddy 2, ball 2]
Here is what I want
[sorry 4, train 2, teddy 2, ball 2, bat 1];
What is wrong in my code? How do I do it?
The problem is in your getMostFrequentToy() method:
Replace
if (toyList.get(i).getCount() > maximum)
maximum = toyList.get(i).getCount();
position = i;
with
if (toyList.get(i).getCount() > maximum) {
maximum = toyList.get(i).getCount();
position = i;
}
because you want to get the position that corresponds to that maximum.
You have some in-efficiencies in your code. Every single time you call getMostFrequentToy(), you are iterating over the whole list, which may be fine as you are constantly removing objects, but you really don't need to make new Toy objects for those that already exist in the list.
So, this is "better", but still not sure you need to getThatToy when you should already know which one is the most frequent.
String frequent;
for (int i = size; i > 0; i--) {
frequent = getMostFrequentToy();
t.add(new Toy(frequent));
t.get(count).setCount(getThatToy(frequent).getCount());
toyList.remove(getThatToy(frequent));
count++;
}
Anyways, I think the instructions asked you to return the Toy object, not its name.
It's quite simple, just keep track of the max count.
public Toy getMostFrequentToy() {
Toy mostFrequent = null;
int maximum = Integer.MIN_VALUE;
for (Toy t : toyList) {
if (t.getCount() > maximum)
mostFrequent = t;
}
return t;
}
Now, the above code can become
public void sortToysByCount() {
ArrayList<Toy> t = new ArrayList<Toy>();
// int count = 0;
int size = toyList.size();
Toy frequent;
for (int i = size; i > 0; i--) {
frequent = getMostFrequentToy();
t.add(frequent);
// t.get(count).setCount(frequent.getCount()); // Not sure about this
toyList.remove(frequent);
// count++;
}
toyList.clear();
toyList.addAll(t);
}
Realistically, though, when you want to sort, you really should see how to create a Comparator for your Toy objects.