2009-11-05 2 views
1

ArrayList가있는 메소드를 만들어야합니다. 이 ArrayList에서 짝수를 제거해야합니다. 나는 그것을위한 코드를 작성했지만 논리적 인 오류가있다. ,ArrayList에서 짝수를 제거하십시오.

Unsorted List: [11, 45, 12, 32, 36] 
This is Even Number:12 
This is Even Number:36 
Sorted List: [11, 32, 45] 

내가이 짝수로 (32)는 짝수로 적발되지 않는 이유 궁금 :

static void sortList(){ 

    List <Integer> number=new ArrayList <Integer>(); 

    number.add(11); 
    number.add(45); 
    number.add(12); 
    number.add(32); 
    number.add(36); 

    System.out.println("Unsorted List: "+number); 

    for (int i=0;i<number.size();i++){  
     int even=number.get(i)%2;  
     if (even==0){ 
      System.out.println("This is Even Number:"+ number.get(i)); 
      number.remove(i); 
     }  
    } 

    Collections.sort(number); 
    System.out.println("Sorted List: "+number); 

} 

코드의 출력은 다음과 같습니다

여기 내 코드입니다 같은 위치에서 다른 짝수를 사용하여 테스트했지만 그 결과는 같습니다. 왜 인덱스에서 (3) 어떤 짝수도 잡을 수없는 일이 일어나는 이유는 무엇입니까? 나는 정말로 이유를 궁금해하고있다. 그러니 어느 누구도이 일을 도와 주실 수 있으며,이 솔루션을 구현하는 다른 더 좋은 방법이 있습니다.

감사합니다.

+0

당신은 목록을 변경하는이 뭔가에 많은 청소기를 그것의 사용을 돌 수 있었다 그것을 반복하는 동안. 간단한 수정은 목록을 거꾸로 반복하는 것입니다. –

답변

5

Iterator를 사용해라. 당신이 필요로하는 remove() 방법이 있습니다.

List<Integer> numbers = new ArrayList<Integer>(); 

numbers.add(11); 
numbers.add(45); 
numbers.add(12); 
numbers.add(32); 
numbers.add(36); 

System.out.println("Unsorted List: " + numbers); 

for (Iterator<Integer> iterator = numbers.iterator(); iterator.hasNext();) { 
    Integer number = iterator.next(); 
    if (number % 2 == 0) { 
     System.out.println("This is Even Number: " + number); 
     iterator.remove(); 
    } 

} 

Collections.sort(numbers); 
System.out.println("Sorted List: " + numbers); 
7

목록에서 항목을 제거하면 그 이후의 모든 항목의 색인이 변경됩니다!

특히, 구현에서 32는 다른 짝수 바로 뒤에 오는 것처럼 제거되지 않습니다.

이 같은 목록을 통해 반복자, 대신 그 반복자의 remove 오퍼레이션, 뭔가 사용하는 것이

: 당신이 그것을 통해 반복하는 동안 목록에서 항목을 제거하면

for(Iterator i = number.iterator(); i.hasNext();) { 
    if (isEven(i.next()) { 
     i.remove(); 
    } 
} 
+0

반복자는'ArrayList'에 대해 O (n^2) 성능을 제공합니다. 그것은 문제 일 수도 있고 아닐 수도 있습니다. –

+1

교대로, 끝에서 뒤로 걸어 – Mikeb

+0

그것은 할 것인가? 이상하게 들리네 ... 어쨌든, List (실제로 ArrayList 또는 다른 종류의 List 인 경우 무시)을 사용하는 경향이 있으며 iterating이 빠를 것이라고 가정합니다. 필자는 성능 문제가 발생하지 않는 한 성능 최적화에 시간을 투자하고 싶지 않습니다 ... –

1

를, 당신 ' 루프 색인을 조정해야합니다. 잊어 버리지 말고, 요소를 제거하면 목록의 길이가 하나 줄어들고 그 뒤의 모든 요소의 인덱스가 효율적으로 "뒤섞입니다".

1

문제는 (다른 사람들이 언급 한 것처럼) 트래버스하는 동안 목록을 수정한다는 것입니다. "i--;"을 추가하십시오. 귀하의 "if (짝수 == 0)"블록 내부에 줄을 그어보십시오. 이와 같이 :

for (int i=0;i<number.size();i++){ 
    int even=number.get(i)%2; 

    if (even==0){ 
     System.out.println("This is Even Number:"+ number.get(i)); 
     number.remove(i); 

     // Add this: 
     i--; 
    } 
} 
4

목록 색인 변경에 대한 답변은 모두 정확합니다. 그러나 ArrayList에서 항목을 제거하는 것은 실제로 다음 항목을 모두 뒤집어야하기 때문에 느립니다. 대신 짝수 만 포함 된 새 목록을 만든 다음 이전 목록을 버리는 것이 좋습니다. 반복자 기반 제거 코드를 다른 대답에 사용하려면 작은 결과는 그대로, LinkedList를 사용하면 큰 데이터 집합의 경우에는 정상적으로 작동합니다. (나는 그것이 이름이라고 믿는다; 나의 자바는 틀림없이 약간 녹슬다.)

+1

* ArrayList *를 의미합니다. –

+0

@Kevin Bourrillion : 당신 말이 맞습니다. 반영하도록 편집 됨. –

0

이상한 요소를 필터링하는 멋진 방법이 있습니다. 대신 수동으로 컬렉션을 통해 반복의, Apache Commons Collections

// apply a filter to the collection 
CollectionUtils.filter(numbers, new Predicate() { 
    public boolean evaluate(Object o) { 
     if ((((Integer) o) % 2) == 0) { 
      return false; // even items don't match the filter 
     } 
     return true; // odd items match the filter 
    } 
}); 

그것은이 실제로 읽고 이해하기 쉽게인지 논란의 여지가있어에 작업을 오프로드,하지만 더 재미 있어요. 특정 종류의 술어가 자주 사용되면 정적 상수로 리팩토링되어 그 곳곳에서 재사용 될 수 있습니다.

CollectionUtils.filter(numberList, ODD_PREDICATE); 
0

내가

fun main(args: Array<String>) { 

var numbers = arrayList(1,2,3,4,5,6) 
println(numbers.filter{it %2 == 0}) 

} 

결과 (Intelliji 코 틀린에) 무엇을 = 2,4,6