问题
I have an arraylist of integers, i need to compute the average of the integers excluding the smallest two integers. I keep trying different ways of doing this but think what I want to do is find min1, remove it and then find min2 then remove that.
public double computeAverageWithoutLowest2()
{
ArrayList<Student> newscores = new ArrayList<Student>(scores);
int newtotalScores=0;
int newavg=0;
int min1 = 0;
int min2 = 0;
min1 = newscores.get(0).getScore();
for (int i = 0; i< newscores.size(); i++)
{
if (newscores.get(i).getScore() < min1)
{
min1 = newscores.get(i).getScore();
}
}
now I want to remove min1 from my arraylist. I have obviously tried newscores.remove(min1); which does not work. How can I figure out what spot in the array min1 is and then delete it?
Any help would be great thanks!!
Alright so now after looking at the comments I changed my code to:
ArrayList<Student> newscores = new ArrayList<Student>(scores);
int newtotalScores=0;
int newavg=0;
int minPos1 = 0;
int minPos2 = 0;
int min1 = newscores.get(0).getScore();
int min2 = newscores.get(0).getScore();
for(int i = 0; i < newscores.size(); i++)
{
if(newscores.get(i).getScore() < min1)
{
min1 = scores.get(i).getScore();
minPos1 = i;
}
}
newscores.remove(minPos1);
for(int j = 0; j < newscores.size(); j++)
{
if(newscores.get(j).getScore() < min2)
{
min2 = scores.get(j).getScore();
minPos2 = j;
}
}
newscores.remove(minPos2);
This way works to remove min1, but does not work to remove min2 instead it just removes the same position that min1 removed.
回答1:
Why don't you simply use remove, indexOf and min:
newscores.remove(newscores.indexOf(Collections.min(newscores)));
Do it twice if you want to remove the two smallest items.
回答2:
This solution is faster than calling Collections.min()
two times because you just need one iteration but you need to save the position as well to avoid going through the array again to remove the lowest elements.
ArrayList<Student> newscores = new ArrayList<Student>(scores);
Student min1;
Student min2;
int minPos1;
int minPos2;
for(int i = 0; i < newscores.size(); i++) {
if(newscores.get(i).getScore() < min1.getScore()) {
min1 = student;
minPos1 = i;
} else if (newscores.get(i).getScore() < min2.getScore()) {
min2 = student;
minPos2 = i;
}
}
newscores.remove(minPos1);
newscores.remove(minPos2);
Another approach would be to use a ordered collection like a PriorityQueue
which is faster because you enter the elements ordered don't have to look for the lowest.
回答3:
Don't remove the elements from the list, just keep the lowest two you found so far separate when iterating through it and only add them to the sum when you find an even lower element. This way you can compute the average in one iteration.
To give you an idea:
List<Integer> scores = Arrays.asList(2, 3, 4, 5, 0, 6, 1, 7);
int min1 = scores.get(0);
int min2 = scores.get(1);
int sum = 0;
int swap = 0;
for (int i = 2; i < scores.size(); i++) {
int score = scores.get(i);
if (score < min1) {
swap = min1;
min1 = score;
score = swap;
}
if (score < min2) {
swap = min2;
min2 = score;
score = swap;
}
System.out.println("adding " + score);
sum += score;
}
System.out.println(String.format("lowest scores: %d and %d",min1, min2));
System.out.println(sum / (scores.size() - 2.0));
Prints
adding 4
adding 5
adding 3
adding 6
adding 2
adding 7
lowest scores: 0 and 1
4.5
来源:https://stackoverflow.com/questions/19883788/removing-the-smallest-2-elements-in-an-arraylist-in-java