用递归函数判断传入值是否为游戏合法得分并简化现有代码
游戏合法得分递归判断实现
需求说明
- 游戏得分仅由4分、9分两类固定分值累加得到,两类分值可任意次数叠加使用
- 要求用递归逻辑实现判断函数,验证传入的无符号整数是否为合法得分
- 判定参考:
- 26可拆为9+4+9+4,返回true
- 19无法拆分出4和9的有效组合,返回false
- 附加问询:现有实现能否简化
现有代码
public static bool IsScore(uint aScore) { if (aScore % 4 == 0 || aScore % 9 == 0 || aScore % 13 == 0) { return true; } else if (aScore % 9 !< 4 || aScore % 4 !< 9) { return false; } else { return IsScore(aScore - 13); } }
代码问题与修正
现有代码存在两处核心问题:
- 语法错误:C#不存在
!<运算符,条件分支无法编译通过 - 逻辑错误:
- 额外加入13取余判断无意义(13本身就是4+9的组合,无需单独作为合法判定条件)
- 递归出口设计错误,没有覆盖“分数减到负数说明凑不出来”的终止场景
正确递归实现
递归核心逻辑为:每次尝试扣除一次4分或9分,对剩余分数继续递归判断,直到触发终止条件:
- 剩余分数为0:刚好凑满,判定为合法
- 剩余分数小于0:无法再扣减分值,判定为非法
代码如下:
public static bool IsScore(uint aScore) { // 终止:分数刚好为0,合法 if (aScore == 0) return true; // 终止:分数不足4分且不为0,无法继续扣减,非法 if (aScore < 4) return false; // 递归:任意一种扣减路径能凑出即为合法 return IsScore(aScore - 4) || IsScore(aScore - 9); }
简化方案
可以大幅简化,分为两个方向:
- 递归版本简化:用表达式体合并判断逻辑,减少冗余代码:
public static bool IsScore(uint aScore) => aScore == 0 ? true : aScore < 4 ? false : IsScore(aScore - 4) || IsScore(aScore - 9);
- 非递归O(1)简化:根据弗罗贝尼乌斯数定理,4和9的最大公约数为1,所有大于等于
(4-1)*(9-1)=21的正整数都可以拆为4和9的组合,仅需预先记录小于21的非法值,无需递归即可直接判定,性能远高于递归实现。
内容的提问来源于stack exchange,提问作者D_C
相关产品推荐
相关产品推荐

