2014-09-26 3 views
1

할당은 int 배열에서 두 번째로 큰 짝수 int를 찾는 메서드를 만드는 것입니다. 모든 라이브러리의 메소드를 사용하는 것이 제한되어 있습니다.배열에서 두 번째로 큰 짝수 int를 찾는 효율적인 방법

가 methodI를 호출하는
public static int getSecondLargestEven(int[] ary) { 


int i; 

    aryLength = ary.length; 
    int largestEven = -1; 
    int secondLargestEven = -1; 

    for (i = 0; i < aryLength; i++) { 
     if (ary[i] % 2 == 0) { 
      if (ary[i] > largestEven) { 
       if (largestEven != -1) 
        secondLargestEven = largestEven; 

       largestEven = ary[i]; 
      } else { 
       if (ary[i] != largestEven) { 
        if (secondLargestEven == -1 || ary[i] >= secondLargestEven) { 
         secondLargestEven = ary[i]; 
        } 
       } 
      } 
     } 
    } 

이전에도 다른 두 개 이상의 어떤 메서드 호출을 가지고 배열이 필요합니다

다음은 모든 경우에 작동하는 내 코드입니다. 따라서 secondLargestEven == -1 일 때 중복이 있다는 것을 알고 있습니다.

목적을 달성하는 데 더 효율적인 (적은 수의 루프 사용, 적은 메모리 할당) 방법이 있습니까? 내 코드의 논리를 어떻게 향상시킬 수 있습니까? 코드 전체를 개선하려면 어떻게해야합니까? 나는 MagicNumber -1을 secondLargestEven과 largestEven에 할당하는 것이 맘에 안 든다. 기술적 인 이름으로 EVENS를 보유하고 있기 때문이다. 배열에서 유효한 짝수 정수를 secondLargestEven 및 largestEven에 할당하기 위해 루프를 사용하는 것이 효과적일까요? 그렇다면 검색을 계속 하시겠습니까? 미리 감사드립니다.

+0

(런타임, 리소스 또는 일반 스타일/아키텍처) 개선하려는 작업 코드의 경우 [CodeReview.SE] (http://codereview.stackexchange.com/) – Ordous

+0

코드에서 가장 잘 처리 할 수 ​​있습니다. 코드 비록 공연이 좋지 않더라도, 공연 측면에서 보면 효율적이라고합니다.코드 우아함과 최상의 효율성은 종종 호환되지 않습니다. – Joel

+0

@Joel 나는 점근 적 효율성이 대부분의 경우 우아함과 매우 양립 할 수 있다고 주장합니다. 이제 1 바이트를 덜 사용하면 추악한 코드가 생성 될 수 있습니다. – Ordous

답변

4

largestsecond 변수가 -1 인 경우 명시 적으로 확인하지 않아도 코드를보다 명확하게 만들 수 있습니다.

이러한 변수를 루프 전에 Integer.MIN_VALUE으로 설정하면 다른 모든 값보다 먼저 배열에 두 개의 값이 있고 두 값 모두 Integer.MIN_VALUE이라는 가정과 동일합니다.

public static int secondLargestEven(int[] x) { 

    int largest = Integer.MIN_VALUE; 
    int second = Integer.MIN_VALUE; 

    for (int i = 0; i < x.length; i++) { 
     if (x[i] % 2 == 0) { 
      if (x[i] > largest) { 
       second = largest; 
       largest = x[i]; 
      } else if (x[i] > second) { 
       second = x[i]; 
      } 
     } 
    } 

    return second; 

} 

편집 - 난, 난 당신이 홀수가있는 경우를 건너 루프 내부 continue 문을 사용하여 중첩 한 레벨을 제거 할 수 있다는 점에서 던져 줄 알았는데 어떤 사람들은 비록 위의 코드보다 이해하기가 어렵다고 생각합니다.

루프 내부에서 명시적인 제어 흐름을 사용하지만 나쁜 경우 중첩 수준을 제거합니다.

public static int secondLargestEven(int[] x) { 

    int largest = Integer.MIN_VALUE; 
    int second = Integer.MIN_VALUE; 

    for (int i = 0; i < x.length; i++) { 
     if (x[i] % 2 != 0) 
      continue; 
     if (x[i] > largest) { 
      second = largest; 
      largest = x[i]; 
     } else if (x[i] > second) 
      second = x[i]; 
     } 
    } 

    return second; 

} 

그냥 재미있는 생각 ... 당신이 더 효율적하려면 하스켈에서,이 기능은, 한 줄

import Data.List (sort) 

secondLargestEven = (!! 1) . reverse . sort . filter even 

작성하거나 할 수

import Data.List (sortBy) 
import Data.Ord (comparing) 

secondLargestEven = (!! 1) . sortBy (comparing negate) . filter even 
+0

에 속하기 때문에이 질문은 주제와는 다른 것으로 보입니다. 감사합니다! 확실히 읽는 것이 더 쉬워 보입니다. – qnob

+1

원한다면'Integer.MIN_VALUE'를'-2147483648'으로 대체 할 수 있습니다. 제 의견으로는 코드가 덜 명확 해집니다 :) –

+0

빠른 질문 : x.length를 int 타입의 변수에 할당하는 것이 더 효율적입니까? 루프를 반복 할 때마다 .length()를 호출하지 않겠습니까? – qnob

0

이것은 단지 재미있는 구현입니다.

이 방법(나는 그것을보고 기운) 매우 비효율적이지만 짝수 :

방법은 배열은 두 번째로 큰 짝수가있는 경우에만 작동 두 번째로 큰 반환합니다.

관련 문제