修改版帕斯卡三角实现中非侧边元素res计算逻辑错误排查
修改版帕斯卡三角实现中非侧边元素res计算逻辑错误排查
嘿,我来帮你梳理下问题出在哪~
首先,你现在用的 res = res * (i - j + 1) / j 这个公式,是标准帕斯卡三角的组合数递推公式,它的前提是每一行的第一个元素固定为1,且每个元素本质是组合数C(i,j),由上一行左右两个元素相加得到。但你的修改版三角规则完全不同:侧边元素是递增序列(不是固定1),中间元素依然要遵循“上方两个元素之和”的规则——这时候组合数公式就完全不适用了,因为你的三角已经不是基于组合数生成的了。
问题具体分析
看你的代码逻辑:
- 当
i==0 || j==0时,res++,这确实能让每行的第一个元素依次是1、2、3、4...(符合你侧边递增的要求) - 但非侧边元素用组合数公式计算,得到的结果并不是“上方两个元素之和”,而是组合数的值,这就和你想要的规则矛盾了。比如当rows=5、level=3时,你的代码生成的第3行是
4 12 12 4,但按照规则应该是4 7 7 4(上一行是3 4 3,中间元素是3+4=7、4+3=7),明显不符合预期。
解决方案:换用基于“上一行元素求和”的生成方式
因为你的三角依赖上一行的元素值,所以用数组存储每一行的结果是最直观的方式,这样当前行的中间元素可以直接取上一行的对应位置相加。这里给你修正后的代码示例:
void printTriangle2(int rows, int level) { int i, j, space, max = 0; // 用二维数组存储每一行的元素,适配rows范围内的三角规模 int triangle[rows][rows]; for (i = 0; i < rows; i++) { // 初始化当前行的侧边元素,满足递增要求 triangle[i][0] = i + 1; triangle[i][i] = i + 1; // 计算中间元素:严格等于上一行j-1和j位置的元素之和 for (j = 1; j < i; j++) { triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j]; } // 打印行前空格,保持三角形状 for (space = 1; space <= rows - i; space++) { printf(" "); } // 打印当前行元素,同时统计目标level的最大值 for (j = 0; j <= i; j++) { printf("%4d", triangle[i][j]); if (i == level && triangle[i][j] > max) { max = triangle[i][j]; } } printf("\n"); } printf(" the max value is : %d", max); }
为什么这个方案可行?
- 二维数组直接对应三角的结构,逻辑清晰易懂
- 侧边元素直接赋值为
i+1,完美满足“递增替代固定1”的要求 - 中间元素严格按照“上方两个元素之和”计算,完全符合你设定的规则
- 打印时顺便统计目标level的最大值,流程更顺畅
如果担心二维数组的内存占用,也可以用一维数组滚动更新(从后往前计算当前行,避免覆盖上一行未使用的值),不过对于常规规模的rows来说,二维数组的方式已经足够简单好用。
备注:内容来源于stack exchange,提问作者michael aa
相关产品推荐
相关产品推荐

