2017-01-04 2 views
0

Collatz 시퀀스에서 번호가있는 반복적 인 호출 수를 계산하고 싶습니다. 하지만 더 큰 숫자 예를 들어 4565458458재귀 호출시 분할 오류

#include <cstdlib> 
#include <iostream> 
#include <string> 
#include <sstream> 
using namespace std; 

int f(int value){ 
    if(value==1) return 1; 
    else if(value%2 == 0) return value/2; 
    else return 3*value+1; 
} 

int g(int value){ 
    if(value == 0) return 0; 
    if (f(value)==1) return 1; 
    return 1 + g(f(value)); 
} 

int main(int argc, char *argv[]){ 
    int nSteps=0; 
    istringstream iss(argv[1]); 
    int; 
    if(!(iss >> num).fail()){ 
     if(num < 0) cout << "0" << endl; 
     else{ 
      nSteps = g(num); 
      cout << "Result: " << nSteps << endl; 
     } 
    } 
    else{ 
     cout << "Incorrect line paramaters: ./g n" << endl; 
    } 
    return 0; 
} 
+0

스택 오버플로에 오신 것을 환영합니다! [디버거] (https://en.wikipedia.org/wiki/Debugger)를 사용하여 코드를 단계별로 실행하는 방법을 배워야 할 필요가있는 것 같습니다. 좋은 디버거를 사용하면 한 줄씩 프로그램을 실행하고 예상 한 곳에서 벗어난 곳을 볼 수 있습니다. 프로그래밍을 할 때 필수적인 도구입니다. 추가 읽기 : [작은 프로그램을 디버깅하는 방법] (https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). –

+3

충분히 반복하면 스택 오버플로가 발생할 가능성이 높습니다. – doctorlove

+0

프로그램이 올바르지 않습니다. ': 24 : 17 : 오류 :'num '이 (가)이 범위에서 선언되지 않았습니다.'오류로 인해 컴파일되지 않습니다. –

답변

4

프로그램은 많은 입력을 위해 많은 스택 메모리를 사용합니다.

또한 f는 동일한 입력 및 출력 유형 (원래는 부호없는 long long을 입력으로, int를 출력으로 가짐)이 있어야합니다. 그렇지 않으면 결과가 잘못됩니다.

재귀없이 g를 먼저 재 작성하고, tail-recursion을 사용하여 g를 효율적으로 만드는 방법을 조사 할 것을 권장합니다 (현재 변형은 아마도 이것을 지원하지 않습니다).

다른 제안 된대로 디버거를 사용하는 것이 좋습니다. 특히 'g'를 호출하기 전에 충돌이 발생하는 경우 좋습니다.

마지막으로 'num < 0'은 서명되지 않은 'num'에 대해 의미가 없습니다.

+1

'f (value)'를 두 번 계산하면 아마도 컴파일러가 잠재적 꼬리 재귀 최적화를 돕지 못할 것입니다 –

관련 문제