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;
}