搜索一对的两个元素并替换其中一个元素

Search both elements of a pair and replace either element

给定一对整数 p,我希望能够用 3 替换其中的任何 2,反之亦然,所以我做了这样的事情:

pair<int,int> f(pair<int, int> p) {

    if (p.first == 2)
        p.first = 3;
    else if (p.first == 3)
        p.first = 2;

    if (p.second == 2)
        p.second = 3;
    else if (p.second == 3)
        p.second = 2;

    return p;
}

但是,如果我想要替换的不仅仅是这两个数字,而且每个数字都替换为另一个,那么编写该函数会很烦人。对于这个例子,我如何做到这一点,而不需要编写四个 if 语句,或者使用更少的代码以便它可以扩展到更多可能需要替换的数字?

您可以使用 std::map 将要替换的内容存储为键,将替换内容存储为值:

std::pair<int, int> f(std::pair<int, int> p) {
    static const std::map<int, int> replacements = {
        { 2, 3 },  // 2 -> 3
        { 5, 7 }   // 5 -> 7
        // Add more replacements
    };

    auto it = replacements.find(p.first);
    if (it != replacements.end()) {
        p.first = it->second;
    }

    // Same with p.second

    return p;
}

您也可以通过引用来删除不必要的副本:

void f(std::pair<int, int>& p) {
    // Same as above, but no return 
}

首先,我要排除 p.firstp.second 之间的重复。

void maybe_replace_element(int& element)
{
    if (element == 2)
        element = 3
    else if (element == 3)
        element = 2
}

pair<int,int> f(pair<int, int> p) {
    maybe_replace_element(p.first);
    maybe_replace_element(p.second);
    return p;
}

这将 if 语句的数量减半。

那么,如果你有更多的数字要添加,我认为继续 else if 模式是合理的:

void maybe_replace_element(int& element)
{
    if (element == 2)
        element = 3
    else if (element == 3)
        element = 2
    else if (element == 5)
        element = 7
    else if (element == 8)
        element = 12
}

但您也可以使用 std::unordered_map:

const std::unordered_map<int, int> REPLACEMENTS = {
    {2, 3}, // Replace 2 with 3.
    {3, 2}, // Replace 3 with 2.
    {5, 7}, // etc.
    {8, 12}
};

void maybe_replace_element(int& element)
{
    auto replacement = REPLACEMENTS.find(element);
    if (replacement != REPLACEMENTS.end())
        element = replacement->second;
}