C++ 多条件命中与分隔输出

当一个输入可能同时满足多个条件,并且题目要求输出所有命中的结果时,条件之间不是互斥关系。此时应分别判断每个条件,而不是使用只选择一个分支的 if ... else if ... 链。

独立判断与互斥分支

例如,要输出正整数 n3、5、7 中所有能整除它的数,可以用取余判断整除:

n % d == 0

其中余数为 0 表示 n 能被 d 整除。因为 15 可以同时命中 35,三个判断应彼此独立:

if (n % 3 == 0) { /* 输出 3 */ }
if (n % 5 == 0) { /* 输出 5 */ }
if (n % 7 == 0) { /* 输出 7 */ }

如果改成 if ... else if ...,第一个成立的分支执行后,后续分支不会再判断,因此只能得到一个结果。else if 适合“至多选择一个结果”的互斥分类;多个条件可以同时成立时,应使用独立 if,或者先收集全部命中结果再统一处理。

用“是否已有输出”控制分隔符

连续输出多个结果时,常见格式是元素之间有空格、首尾没有多余空格。与其枚举单项、两两组合和全部组合,不如维护一个状态:前面是否已经输出过元素。

#include <iostream>

int main()
{
    int n;
    std::cin >> n;

    bool has_output = false;

    if (n % 3 == 0) {
        std::cout << 3;
        has_output = true;
    }

    if (n % 5 == 0) {
        if (has_output) std::cout << ' ';
        std::cout << 5;
        has_output = true;
    }

    if (n % 7 == 0) {
        if (has_output) std::cout << ' ';
        std::cout << 7;
        has_output = true;
    }

    return 0;
}

状态的含义是:

  • false:当前元素是第一个,直接输出;
  • true:前面已有元素,先输出分隔符,再输出当前元素。

这里用 bool 比用 int flag = 0/1 更直接地表达二值语义。核心模式不是变量名 flag,而是“在非首个元素之前输出分隔符”。它同样适用于逗号分隔、日志字段拼接和简单文本序列化。

更易扩展的写法

候选值增多时,可以把重复判断改为循环:

const int divisors[] = {3, 5, 7};
bool has_output = false;

for (int d : divisors) {
    if (n % d != 0) continue;
    if (has_output) std::cout << ' ';
    std::cout << d;
    has_output = true;
}

这种写法的复杂度随候选数量线性增长;枚举所有命中组合则会迅速膨胀,也更容易遗漏。

边界与检查

  • 如果没有任何条件命中,应该输出什么,必须由题目或接口契约决定;不能自行假定为空输出、0 或提示文字。
  • 不应默认末尾多余空格一定会被接受。严格评测、协议文本和快照测试可能逐字符比较输出。
  • 候选顺序决定输出顺序;若要求升序或指定顺序,应按该顺序检查或先收集后排序。
  • 测试应覆盖:无命中、单个命中、多个命中和全部命中,而不只是普通输入。

相关知识

  • 编程范式与命名约定
# 知识库 # C++