提问人:Nicholas Yamasaki 提问时间:10/2/2022 最后编辑:PabloNicholas Yamasaki 更新时间:10/2/2022 访问量:360
如何立即检查一组对是否有逗号?
How can I check, straight away, if a set of pairs have a commom number?
问:
假设我们有 4 对,例如:
pair<int, int> P1(1, 2);
pair<int, int> P2(3, 1);
pair<int, int> P3(2, 1);
pair<int, int> P4(1, 5);
我怎样才能直接比较这 4 对并得出结论,它们都有共同点的数字 1?我只能想到两个两个比较,但这对很多配对来说都是很多工作......
是否有某些函数可以对任何给定的对集执行此操作?
答:
在您给出的示例代码中,您需要分别检查每一对(、 等)(例如 )。P1
P2
if (P1.first == 1 || P1.second == 1 || P2.first == 1 || <etc> )
如果您坚持拥有 P1
,...P4
作为不同的变量,没有捷径可走,因为您已经定义了 、 、 ... 以一种在它们之间不强加逻辑或结构关系的方式。(例如,不能保证它们在机器内存中的位置 - 它们可能在一起,也可能在完全不相关的内存位置)。P1
P2
P4
但是有多个具有顺序名称的变量,例如 、 、 .....表示您需要使用原始数组(例如)或标准容器(例如)。如果您使用原始数组或标准容器来构建代码,则有一些选项。例如,原始数组;P1
P2
pair<int, int> P[4]
vector<pair<int, int> > P
std::pair<int, int> P[4];
// set the four elements of P
bool has_one = false;
for (int i = 0; has_one == false && i < 4; ++i)
if (P[i].first == 1 || P[i].second == 1) has_one = true;
它可以很容易地扩展到任意数量的对,只要该数字在编译时是固定的。请记住,数组索引从零开始,而不是从 1 开始(即 存在于上述内容中,但不存在)。P[0]
P[4]
这种代码的危险在于没有正确更新数字(例如,将 from 的元素数更改为 ,但忘记在循环中进行相同的更改)。P
4
27
比起使用原始数组,更好的选择是使用标准容器 - 特别是如果你想用一组对做很多事情。如果在编译时对数是固定的,则可以将上述定义更改为使用标准容器。P
array
std::array<std::pair<int, int>, 4> P; // array is from standard header <array>
// assign the four elements of P (code omitted)
与使用原始数组相比,它提供了许多优势。
如果在编译时不知道对数(例如,该数是根据运行时读取的值计算的),则可以使用另一个标准容器,例如
// compute n as the number of elements
std::vector<std::pair<int, int> > P (n);
在所有情况下,原始数组(注意避免检查比数组更多的元素)和标准容器都可以在循环中使用。
但是,最好(因为它不太容易出错)避免 - 在可能的情况下 - 使用循环,而是使用 C++ 标准库提供的算法。例如(C++11 及更高版本),您可以执行以下操作
#include <algorithm>
#include <vector>
int main()
{
// compute n as the number of elements (code omitted)
std::vector<std::pair<int, int>> P(n);
// populate elements of P (code omitted)
auto check_if_one = [](std::pair<int, int> a)
{return a.first == 1 || a.second == 1;};
bool has_one = (std::find_if(std::begin(P), std::end(P), check_if_one) != std::end(P));
}
这样做的优点是,代码始终正确地考虑 中的元素数。计算上述值的方法都是相同的,无论原始数组、a 、a 还是标准库中的任何其他容器。P
has_one
P
std::array
std::vector
没有“内置”的帮助程序来检查所有货币对是否都包含某个数字,但这是一个相当容易的操作!
为此,您需要一个接收对列表的函数。
bool allPairsShareNumber(list<pair<int, int>> pairs, int number) {
return all_of(pairs.begin(), pairs.end(), [&number](pair<int,int> pair){
return pair.first == number || pair.second == number;
});
}
然后你可以把列表传递给函数!
pair<int, int> P1(1, 2);
pair<int, int> P2(3, 1);
pair<int, int> P3(2, 1);
pair<int, int> P4(1, 5);
list<pair<int, int>> pairList = { P1, P2, P3, P4 };
bool doTheyAllContain1 = allPairsShareNumber(pairList, 1);
评论
list
allPairsShareNumber
评论
c
c
P1.first
P1.second