0

C++ で解決すべき問題は次のとおりです。

GCD ( 2m , 2n )         =  2 * GCD( m , n )
GCD ( 2m , 2n+1 )       = GCD ( m , 2n+1 )
GCD ( 2m+1,  2n+1 ) = GCD ( n-m , 2m+1 )  (m<n)
GCD ( m , m )       = m

ここに私が書いた関数があります:

int GCD(int n1, int n2)
{
    bool n1Zoj, n2Zoj;
    n1Zoj = (n1%2 == 0);
    n2Zoj = (n2%2 == 0);

    if(n1Zoj && n2Zoj)
        return 2 * GCD(n1/2, n2/2);

    if(n1Zoj && !n2Zoj)
        return GCD(n1/2, n2);

    if(!n1Zoj && !n2Zoj)
        return GCD((n2-n1)/2, n1);

    if(n1 == n2)
        return n1;
}

(*"Zoj" は私の言語 (ペルシア語) で "Even" を意味します )

2 番目の引数として 5 を渡すと、プログラムがクラッシュし、次のメッセージが出力されます。

Segmentation fault (core dumped)

終了コードは139. g++ をコンパイラとして使用する ubuntu 12.04 で Code::Blocks を使用しています。

更新: プログラムは 5、10、15、20、25 でクラッシュします...

更新:関数の正しい形式は次のとおりだと思います:

int GCD(int n1, int n2)
{
    if (n1 > n2)
        std::swap(n1, n2);

    //std::cout<<"GCD is called with params: "<<n1<<" & "<<n2<<std::endl;
    bool n1Zoj, n2Zoj;

    n1Zoj = (n1%2 == 0);
    n2Zoj = (n2%2 == 0);

    if(n1 == n2)
        return n1;

    if(n1Zoj && n2Zoj)
        return 2 * GCD(n1/2, n2/2);

    if(n1Zoj && !n2Zoj)
        return GCD(n1/2, n2);

    if(!n1Zoj && n2Zoj)
        return GCD(n2/2, n1);

    if(!n1Zoj && !n2Zoj)
        return GCD((n2-n1)/2, n1);
}
4

1 に答える 1

9

が true と評価されたら(n1Zoj && n2Zoj)、どうしますか? あなたが呼ぶ

return 2 * GCD(n1, n2);

まったく同じパラメーターで関数を呼び出すため、無限再帰、スタックの吹き飛ばし、スタック オーバーフロー (セグメンテーション フォールト) が発生します。

プロティップ - デバッグを学ぶ - これがいかに重要であるかは強調しきれません。

于 2012-12-20T12:14:28.357 に答える