C++ 帕斯卡';s三角实现

C++ 帕斯卡';s三角实现,c++,C++,我正试图为帕斯卡三角形编制一个程序,计算nth行中rth值的公式是n/R(右) 我一直在尝试这样实现它: #include <iostream> // std::cout, std::endl #include <iomanip> // std::setw int Pascal(int ,int ); int Factorial( int); int ma

我正试图为帕斯卡三角形编制一个程序,计算
nth
行中
rth
值的公式是
n/R(右)

我一直在尝试这样实现它:

          #include <iostream>     // std::cout, std::endl
          #include <iomanip>      // std::setw
          int Pascal(int ,int );
          int Factorial( int);
          int main () 
          {
           int n=0;//Number of rows in the triangle
           for(int i=12;i>0;i--)
            {
              std::cout << std::setw(i)<<std::endl;
              for (int j=1;j<12-i;j++)
               {
                int r=0; //rth element initialized for each row
                int P= Pascal(r,n);
                std::cout << P ;
                std::cout <<std::setw(2);
                r=r+1;
               }

              n=n+1;

           }
               std::cout<<std::endl;
                   return 0;
           }
           int Pascal(int r,int n)
           {
               int d = n-r; ///Difference of n with r
               int f1; ///factorial of n
               int f2; ///factorial of r
               int f3; ///factorial of (n-r)

               f1=Factorial(n);
               f2=Factorial(r);
               f3=Factorial(d);
               return f1/(f2*f3);

           }
           int Factorial( int begin )
           {
                   int F;
                   if ( begin == 0 )
                   {
                    return 1; 
                   }
                   else
                   {
                     F= begin*Factorial(begin-1);
                   }
              return F;         
             }

有人能告诉我哪里出了问题吗?

您首先遇到的问题是代码的格式问题。这太可怕了。(对不起,真的很可怕。)

第二件事是,您总是打印
Pascal(r,n)
,而它们是常量
0,0
——您应该打印
Pascal(i,j)
,因为
i
j
是循环计数器


顺便说一句,你最好迭代计算阶乘,并使用足够长的整数,你的代码和seg在我的计算机上出错。

你的第一个明显的问题当然是你应该打印Pascal(i,j)。你的第二个更微妙:

递归 帕斯卡三角形的要点在于,它提供了一种计算二项式系数的方法,而无需计算阶乘

问题是阶乘增长非常快,系数如Pascal(1120)=120/(1!*119!},仅等于120,但其命名符和分母的数量级为10^198,不能存储在任何机器整数类型中

查看上的Pascal三角形。整点是递归关系:

Pascal( r, n ) = Pascal( r-1, n-1 ) + Pascal( r, n-1 )
下面是一个简单的解决方案,利用该解决方案(仅打印r,n pascal数):

在最后一行中,您会注意到Pascal(2,4)出现两次,这意味着您的代码将计算它两次。此外,Pascal(3,5)实际上等于Pascal(2,5)。因此您可以计算Pascal(2,5)两次,这意味着计算Pascal(2,4)四次。这意味着当r和n变大时,程序将变得非常慢。我们希望计算每个帕斯卡(i,j)一次,然后保存其值以供其他调用使用。为此,一种简单的方法是使用映射(r,n)对到帕斯卡(r,n)的映射值:std::map。此方法称为memoization。此外,将int更改为long表示大数字,可以得到以下算法:

#include <iostream>
#include <sstream>
#include <map>

typedef long long                                          Integer;
typedef std::map< std::pair< Integer, Integer >, Integer > MemoMap;
typedef MemoMap::iterator                                  MemoIter;

MemoMap memo;

Integer pascal( Integer r, Integer n ) {
    // make sure r <= n/2 using the fact that pascal(r,n)==pascal(n-r,n)
    if( r > n / 2LL )
        r = n - r;

    // base cases
    if( n == 0LL || r == 0LL )
        return 1LL;

    // search our map for a precalculated value of pascal(r,n)
    MemoIter miter = memo.find( std::make_pair( r, n ) );

    // if it exists return the precalculated value
    if( miter != memo.end() )
        return miter->second;

    // otherwise run our function as before
    Integer result = pascal( r - 1LL, n - 1LL ) + pascal( r, n - 1LL );

    // save the value and return it
    memo.insert( std::make_pair( std::make_pair( r, n ), result ) );

    return result;
}

int main( int argc, char *argv[] ) {
    if( argc != 3 ) {
        std::cout << "Expected exactly 3 arguments." << std::endl;
        return -1;
    }

    Integer r, n;

    std::stringstream ss;
    ss << argv[ 1 ] << ' ' << argv[ 2 ];
    ss >> r >> n;

    if( ss.bad() || r < 0LL || n < 0LL || r > n ) {
        std::cout << "Invalid argument values." << std::endl;
        return -2;
    }

    std::cout << pascal( r, n ) << std::endl;

    return 0;
}
#包括
#包括
#包括
typedef长整数;
typedef std::map,Integer>memomomap;
typedef MemoMap::迭代器MemoIter;
备忘录地图备忘录;
整数帕斯卡(整数r,整数n){
//确保已安装(不适用于2升)
r=n-r;
//基本情况
如果(n==0LL | r==0LL)
返回1LL;
//在地图上搜索预先计算的帕斯卡值(r,n)
MemoIter miter=memo.find(std::make_pair(r,n));
//如果存在,则返回预先计算的值
if(斜接!=memo.end())
返回斜接->秒;
//否则像以前一样运行我们的函数
整数结果=帕斯卡(r-1LL,n-1LL)+帕斯卡(r,n-1LL);
//保存值并返回它
插入(std::make_pair(std::make_pair(r,n),result));
返回结果;
}
int main(int argc,char*argv[]){
如果(argc!=3){
标准::cout n){

std::存储以前计算的值并将其用于下一行可能更好。这是一个非常彻底的答案;+1.不客气!我添加了另一个解决方案(无输出格式,您可能可以自己计算出来--使用pascal(n/2,n)大约有(n/2)(log(2)+log(1))/log(10)个数字).如果你满意,请接受答案。
#include <iostream>
#include <sstream>

int pascal( int r, int n ) {
    if( n == 0 )
        return 1;

    if( r == 0 || r == n )
        return 1;

    return pascal( r - 1, n - 1 ) + pascal( r, n - 1 );
}

int main( int argc, char *argv[] ) {
    if( argc != 3 ) {
        std::cout << "Expected exactly 3 arguments." << std::endl;
        return -1;
    }

    int r, n;

    std::stringstream ss;
    ss << argv[1] << ' ' << argv[2];
    ss >> r >> n;

    if( ss.bad() || r < 0 || n < 0 || r > n ) {
        std::cout << "Invalid argument values." << std::endl;
        return -2;
    }

    std::cout << pascal( r, n ) << std::endl;
    return 0;
}
                       Pascal(3,6)                      =
=        Pascal(2,5)        +        Pascal(3,5)        =
= (Pascal(1,4)+Pascal(2,4)) + (Pascal(2,4)+Pascal(3,4)) = ...
#include <iostream>
#include <sstream>
#include <map>

typedef long long                                          Integer;
typedef std::map< std::pair< Integer, Integer >, Integer > MemoMap;
typedef MemoMap::iterator                                  MemoIter;

MemoMap memo;

Integer pascal( Integer r, Integer n ) {
    // make sure r <= n/2 using the fact that pascal(r,n)==pascal(n-r,n)
    if( r > n / 2LL )
        r = n - r;

    // base cases
    if( n == 0LL || r == 0LL )
        return 1LL;

    // search our map for a precalculated value of pascal(r,n)
    MemoIter miter = memo.find( std::make_pair( r, n ) );

    // if it exists return the precalculated value
    if( miter != memo.end() )
        return miter->second;

    // otherwise run our function as before
    Integer result = pascal( r - 1LL, n - 1LL ) + pascal( r, n - 1LL );

    // save the value and return it
    memo.insert( std::make_pair( std::make_pair( r, n ), result ) );

    return result;
}

int main( int argc, char *argv[] ) {
    if( argc != 3 ) {
        std::cout << "Expected exactly 3 arguments." << std::endl;
        return -1;
    }

    Integer r, n;

    std::stringstream ss;
    ss << argv[ 1 ] << ' ' << argv[ 2 ];
    ss >> r >> n;

    if( ss.bad() || r < 0LL || n < 0LL || r > n ) {
        std::cout << "Invalid argument values." << std::endl;
        return -2;
    }

    std::cout << pascal( r, n ) << std::endl;

    return 0;
}
#include <iostream>
#include <sstream>
#include <vector>


typedef long long Integer;

void print_pascal( Integer maxn ) {
    std::vector< Integer > prevRow, currentRow;

    prevRow.resize( maxn + 1 );
    currentRow.resize( maxn + 1);

    prevRow[ 0 ] = 1;
    // print first row.
    std::cout << 1 << std::endl;
    for( Integer currentN = 1 ; currentN <= maxn ; ++ currentN ) {
        // compute & print current row
        currentRow[ 0 ] = currentRow[ currentN ] = 1;
        std::cout << 1;
        for( Integer r = 1 ; r < currentN ; ++ r ) {
            currentRow[ r ] = prevRow[ r - 1 ] + prevRow[ r ];
            std::cout << ' ' << currentRow[ r ];
        }
        std::cout << ' ' << 1 << std::endl;

        // constant time because swap() only swaps internal ptrs.
        currentRow.swap( prevRow );
    }
}

int main( int argc, char *argv[] ) {
    if( argc != 2 ) {
        std::cout << "Expected exactly 1 argument." << std::endl;
        return -1;
    }

    Integer maxn;

    std::stringstream ss;
    ss << argv[ 1 ]; ss >> maxn;

    if( ss.bad() || maxn < 0LL ) {
        std::cout << "Invalid argument values." << std::endl;
        return -2;
    }

    print_pascal( maxn );

    return 0;
}