2014-12-18 2 views
-3

함수 (f)는 항목 수 (n)와 열 수 (c)를 사용하고 열당 항목 배열로 최적의 레이아웃을 반환합니다. 나는 최적을 가능한 한 정사각형이라고 정의한다. 따라서 f (4,4)는 [4,4,4,4]를 반환하고 f (17,4)는 [5,4,4,4]를 반환하고 f (1,4)는 [1,0 , 0,0]. 내 함수는 모든 테스트에서 올바르게 작동하지만, 변경하려고합니다. 이 작업을 수행하고자하는 열망은 성능 향상을 기대하기 때문이 아닙니다. 저는 단지 실험하고 있기 때문에 다른 기법을 배우기를 원합니다.정수가 1이고 그렇지 않으면 0을내는 수식

함수는 제 COL 당 아이템의 최적의 수를 결정함으로써 동작
public static int[] f(int n, int c){ 
     int[] a = new int[c]; 
     if(c>0 && n>=0){ 
      int opt = (n-(n%c))/c; 
      n = n - (opt*c); 
      for(int i = 0;i<a.Length;i++){ 
       a[i] = opt; 
       if(n>0){ 
        a[i]++; 
        n--; 
       } 
      } 
     } 
     return a; 
    } 

:

int opt = (n-(n%c))/c; 

그래서 F (17.4) 4를 수득 할, F (여기서

는 코드 19,4)는 또한 4를 산출하고, f (3,4)는 0을 산출합니다. 그러면 알림이 계산됩니다.

n = n - (opt*c); 

(길이가 c 인) rray를 선택하고 a [i]를 최적 값과 같게 지정하십시오. 마지막으로 알림이 0보다 큰 경우 [i]에 1을 더합니다. 이렇게하면 미리 알림이 배열 전체에 균등하게 분배됩니다. 이것이 내가 바꾸고 싶은 부분입니다. 대신 체크

경우 (N> 0) 및 어레이에 1을 가산 그 I의 모양에 사용할 수있는 화학식있다 : *

a[i] = opt + n*?????; 

따라서 n은 ??? n이 0보다 크면 항상 1이고 n이 0 이하이면 0입니다.

+11

이 아마 더 나은 프로그래머 또는 CompSci SE에 운임 것이다. 이외에도, 일반적으로 변수 이름은 * 끔찍한 *입니다. 변수 이름은 반복 변수가 아닌 한 문자가 아닌 설명 적이어야합니다. – BradleyDotNET

+0

@Bradley와 동의하지만 어떤 상황에서는 단일 문자가 람다 인수에 적절하다고 간주 될 수 있습니다. ('x => x.Age> 5'). –

+0

@KirkWoll 예, 다른 예외가 있습니다 (가장 일반적인 사용 사례에서는 its *가 거의 반복 변수 임). – BradleyDotNET

답변

3

귀하의 질문에 간단한 대답은 조건 연산자와 표현식을 사용하는 것입니다

a[i] = opt + (n > 0 ? 1 : 0); 

(n > 0 ? 1 : 0)0보다 큰 1n 경우, 그리고 0 그렇지 않습니다.


이 점에 유의하십시오. 알고리즘을 구현하는 데있어 명확하고 간결한 방법이 있습니다.

  1. 슬롯간에 균등하게 분배 할 수있는 총 항목 수를 결정하십시오 (average). 이 값은 n/c (정수 나누기 사용)입니다.
  2. 균등하게 분배 된 후에 남을 나머지를 결정하십시오 (remainder). 이 값은 n % c입니다.
  3. 첫 번째 remainder 슬롯에 average + 1 값을 넣고 나머지에는 average을 넣습니다.

이에 대한 구현은 다음과 같습니다

public static int[] Distribute(int total, int buckets) 
{ 
    if (total < 0) { throw new ArgumentException("cannot be less than 0", "total"); } 
    if (buckets < 1) { throw new ArgumentException("cannot be less than 1", "buckets"); } 

    var average = total/buckets; 
    var remainder = total % buckets; 

    var array = new int[buckets]; 

    for (var i = 0; i < buckets; i++) 
    { 
     array[i] = average + (i < remainder ? 1 : 0); 
    } 

    return array; 
} 

그리고 의무의 LINQ 버전 :

public static int[] DistributeLinq(int total, int buckets) 
{ 
    if (total < 0) { throw new ArgumentException("cannot be less than 0", "total"); } 
    if (buckets < 1) { throw new ArgumentException("cannot be less than 1", "buckets"); } 

    var average = total/buckets; 
    var remainder = total % buckets; 

    return Enumerable.Range(1, buckets) 
        .Select(v => average + (v <= remainder ? 1 : 0)) 
        .ToArray(); 
} 
2

bool 표현에서 int을 출력하는 간단한 함수는 어떻습니까?

당신은 다음과 같은 코드에서 이것을 사용할 수 있습니다

:

a[i] = opt + IsPositive(n); 
//opt + 1 if n > 0, opt + 0 if n <= 0 

업데이트 : 측정으로

a[i] = opt + (n > 0 ? 1 : 0); 

: 귀하의 의견에 따라, 당신은 단지 평가를 인라인으로 이동할 수 있습니다 옆으로 : @BradleyDotNET's comment을 프로그래밍상의 모토 중 하나가되어야합니다.

+0

고마워요,하지만이게 내가 찾는 대답이 아니야. 여러 함수 호출을 원하지 않습니다. 간단한 표현식을 찾고 있습니다. –

+1

왜 표현식에 직접 추가하지 않으시겠습니까? 'a [i] = opt + (n> 0? 1 : 0);' – trashr0x

1

수식 사용하려면 : 트릭을 할해야

Math.Max(n - Math.Abs(n - 1), 0)

합니다. 귀하의 코드가 같아야합니다 : 당신이 수학 공식을 찾는 경우 공식에 대한 또 다른 옵션은

Math.Max(Math.Sign(n), 0) 

a[i] = opt + Math.Max(n - Math.Abs(n - 1), 0)

1

, 당신이 찾을거야 확실하지 않다 n = 0에서 함수가 불연속이기 때문입니다.

관련 문제