返回文章
文章

改造:一道题目,多种写法,如何融合?

代码/杂谈
改造:一道题目,多种写法,如何融合?

改造:一道题目,多种写法,如何融合?

这个专题的想法,来源于我做的一道题目:

先输入一个 t,然后输入 t 组数据,对于每组数据,输入两个整数 a 和 b,如果 a 能够被 b 整除, 则输出 YES,否则输出 NO。

关于这道题目有两种写法:if-else和条件运算符:

if-else

if-else

条件运算符

条件运算符

本身这是一道平平无奇的题目,但是我在整理代码的时候突发奇想:我能不能把这两段代码放进一个文件里面,因为我认为题目一样,两种解法,也应该放在一起。

但是众所周知,一山不容二虎——同一个文件下不得以正式代码的形式出现多个main函数。那怎么放进去呢?

我想到了能不能通过做出多个子功能函数,让这些小函数以这两种方法分别完成对数据的判断,然后在main函数里同时让这几个子函数运行,一来包含了完整的所有解法,另一方面还能排查问题(如果几种解法对应的函数输出不一样,就可以快速知道哪个出了问题)

但是在函数的改造上,也不可能是把原函数里的所有的代码都原封不动打包进所谓的f()里,所以如何取舍是一个解决的点。

这里我想的是看原函数的功能流程:输入值(多少组)→输入值(什么值)→判断→输出

解法的差异,通过分析也可以看出,是在于判断一环,所以打包出来的函数它本身已经知道的输入的值,它的功能也就只有判断了。

所以可以这样写:

char* f_if(int a, int b) {
    if (b == 0 || a % b) {
        return "NO";
    }
    return "YES";
}

char* f_condition(int a, int b){
    return (b == 0 || a % b) ? "NO" : "YES";
}

int main(){
    int a, b, t;
    scanf("%d", &t);
    while( t-- ){
        scanf("%d %d", &a, &b);
        printf("%s\n", f_if(a, b));
        printf("%s\n", f_condition(a, b));
    }
    return 0;
}

这道题本身很简单,但多想一步,就能把以前学过的东西串起来。

刚学 C 语言的时候,我习惯把所有代码堆在 main 函数里。后来学了函数,知道可以把重复的代码抽出去。这道题正好提供了一个练习的机会:两种解法功能相同、写法不同,抽成两个函数,放进同一个文件里,不但互不冲突,还能互相验证——同一个输入,哪个输出不对,一眼就能看出来。

这种思路其实不止于这道题,当一段程序里有多种实现方式、每种都需要验证正确性的时候,把不同方案写成并列的函数,统一入口、对比输出,就是一种很实用的调试方法。更进一步,这其实也是“单元测试”的朴素雏形——写好一个函数,用另一个版本给它做交叉验证。

一道简单的 if-else 题,稍微延伸一下,就摸到了代码组织和程序验证的边。平时多这样想一想,写过的每一道题都会比看上去更有价值