2012-09-12 5 views
1

narcissistic number 3에서 9 자리 숫자를 찾고 있습니다. 작업 코드가 있지만 중첩 루프는 사용하기가 번거 롭습니다. 재귀를 사용할 수있을 것 같아요, 어떻게? 귀하의 numC에서 중첩 for 루프를 단순화

#include "stdafx.h" 
#include <time.h> 

int power(int a,int b) 
{ 
    int t=1,i; 
    for (i=0;i<b;i++) 
     t*=a; 
    return t; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    double t0=clock(); 
    int a,b,c,d,e,f,g,h,i; 
    int len=9; 
    for (a=1;a<=9;a++) 
     for (b=0;b<=9;b++) 
      for (c=0;c<=9;c++) 
       for (d=0;d<=9;d++) 
        for (e=0;e<=9;e++) 
         for (f=0;f<=9;f++) 
          for (g=0;g<=9;g++) 
           for (h=0;h<=9;h++) 
            for(i=0;i<=9;i++) 
           { 
            int num=10*(10*(1000000*a+100000*b+10000*c+1000*d+100*e+10*f+g)+h)+i; 
            if (num==power(a,len)+power(b,len)+power(c,len)+power(d,len)+power(e,len)+power(f,len)+power(g,len)+power(h,len)+power(i,len)) 
             printf(" %d ",num); 
           } 
           printf("\n耗时: %f s",(clock()-t0)/CLOCKS_PER_SEC); 

    return 0; 
} 
+0

를 확인? – Sulthan

+0

1 분 걸릴 것 같아요. –

+1

서술 된 것처럼 정수 오버플로가 발생하지 않으면 놀랄 것입니다. bignum 라이브러리를 조사하십시오. – unwind

답변

2

단순히 999,999,999에 (Edit 2 참조) 0까지의 모든 수를 반복한다. 따라서 모든 숫자를 반복 할 필요가 없습니다. 좀 더 효율적인 방법으로 power 기능을 수행 할 수 있습니다

unsigned int num; 
for (num = 0; num < 1000000000; ++num)  // will take long 
{ 
    char digits[15]; 
    unsigned int i, other_num; 
    sprintf(digits, "%09u", i);    // division used here 
    other_num = 0; 
    for (j = 0; j < 9; ++j) 
     other_num += power(digits[j] - '0', len); 
    if (num == other_num) 
     printf(" %d ",num); 
} 

참고 :도 아마 더 이상 효율적이지 불구하고, 당신이 원하는 일을하는 간단한 방법이있다. this question을 참조하십시오.


편집 1 : (참고 : Edit 2 참조)

내가 위키 피 디아 페이지를 통해 읽고있다, 그리고 당신이, 9 len를 설정하지해야 밝혀 당신이있는 경우에 때문에 예를 들어 153 일 경우 other_num1^3 + 5^3 + 3^3이어야합니다 (예 : 위키피디아).

그래서 당신은 다음과 같은 방법으로 루프를 조정해야합니다 :

unsigned int num; 
for (num = 0; num < 1000000000; ++num) 
{ 
    char digits[15]; 
    unsigned int i, other_num, len; 
    len = snprintf(digits, 10, "%u", i); // len returned by snprintf 
    other_num = 0; 
    for (j = 0; j < len; ++j)    // changed 9 to len 
     other_num += power(digits[j] - '0', len); 
    if (num == other_num) 
     printf(" %d ",num); 
} 

편집 2 : 난 그냥 전화 번호는 당신이 정말로하지 않도록 100,000,000에서 시작 것으로 나타났습니다

주의해야합니다 Edit 1. 그럼에도 불구하고, 당신이 당신의 숫자의 범위를 변경해야 할 필요가있을 때를 대비하여 알고있는 것이 좋다고 믿습니다.

+0

정확히 내가 생각한 것뿐만 아니라 그는 9 개의 다른 힘을 사용하므로 효과적으로 배열에 넣을 수 있습니다. – Sulthan

+0

Num는 원래 게시물에서 100000000부터 시작하며 위치 n에서 숫자를 가져 오려면 char 배열에 숫자를 입력 할 필요가 없습니다. num % 10^(n + 1) – Jack

+0

을 사용하여 성능을 향상시킬 수 있습니다. 잭, 네 말이 맞아, 나는 그걸 놓쳤다. 나는 그것을 편집 할 것이다. 또한'num % 10^(n + 1)'은'snprintf'보다 성능이 떨어집니다. '* printf'에는 숫자의 수만큼의 숫자가 있습니다. 귀하의 방법에는 한 부분 ('%'이 붙어 있음)과 한 자리수가 있습니다. – Shahbaz

0

사실, 내가 잘못하지 않는다면 모든 값 (num)을 1에서 10^len까지 검사하고 있습니다. 따라서 간단한 for주기가 1에서 10^len이면 충분합니다. 그런 다음 num에서 숫자를 가져와 전력 값을 계산할 수 있습니다.

우선 1^len, 2^len ... 9^len의 힘을 계산하여 배열에 넣는 것이 좋습니다. 성능이 크게 향상됩니다.

1

환상적인 루프. 무엇 이것에 대해 : - 시간 프로그램 실행을

물론
for(num = 100000000; num <= 999999999; num++) { 
    int compare = 0; 
    for(k = 0; k < 10; k++) { 
     int position = pow(10, k+1); 
     int s = num%position; 
     compare += pow(s, 9); 
    } 
    if(num == compare) { 
     printf("%d\n", num); 
    } 
} 

는 경계 :) 궁금

관련 문제