gpt4 book ai didi

C++ 在 if 语句设置条件为真和 or-ing 循环条件之间的行为差​​异

转载 作者:行者123 更新时间:2023-11-30 01:06:53 27 4
gpt4 key购买 nike

我正在为我的 CS 类(class)开发 Datalog 解释器,我遇到了一个奇怪的问题,我的规则评估需要太多遍才能完成。查看我的代码后,我在下面做了两处修改,修复了我的评估以正确的遍数执行:

//original form
bool addedFacts = false;
for (X x: xs) {
addedFacts = addedFacts || set.insert(x).second;
}
//modified form
bool addedFacts = false;
for (X x: xs) {
if (set.insert(x).second) {
addedFacts = true;
}
}

对我来说,这两个代码结构在逻辑上是等价的。一个执行正确而另一个执行不正确/效率低下是否有原因?以下是所发生问题的可构建示例:

#include <iostream>
#include <set>
#include <vector>

using std::set;
using std::vector;
using std::cout;
using std::endl;

const int CAP = 100;

class Rule {
public:
int factor;
Rule(int factor) {
this->factor = factor;
}
bool evaluateInefficient(set<int>& facts) {
vector<int> data;
bool addedFacts = false;
for (int fact : facts) {
data.push_back(fact);
}
for (int datum : data) {
int newFact = datum * factor;
if (newFact < CAP) {
addedFacts = addedFacts || facts.insert(newFact).second;
}
}
return addedFacts;
}
bool evaluate(set<int>& facts) {
vector<int> data;
bool addedFacts = false;
for (int fact : facts) {
data.push_back(fact);
}
for (int datum : data) {
int newFact = datum * factor;
if (newFact < CAP) {
if (facts.insert(newFact).second) {
addedFacts = true;
}
}
}
return addedFacts;
}
};

int doublyInefficient(vector<Rule>& rules) {
set<int> facts;
facts.insert(1);
bool addedFacts = true;
int passes = 0;
while (addedFacts) {
passes++;
addedFacts = false;
for (Rule rule : rules) {
addedFacts = addedFacts || rule.evaluateInefficient(facts);
}
}
return passes;
}

int singlyInefficient(vector<Rule>& rules) {
set<int> facts;
facts.insert(1);
bool addedFacts = true;
int passes = 0;
while (addedFacts) {
passes++;
addedFacts = false;
for (Rule rule : rules) {
addedFacts = addedFacts || rule.evaluate(facts);
}
}
return passes;
}

int efficient(vector<Rule>& rules) {
set<int> facts;
facts.insert(1);
bool addedFacts = true;
int passes = 0;
while (addedFacts) {
passes++;
addedFacts = false;
for (Rule rule : rules) {
if (rule.evaluate(facts)) {
addedFacts = true;
}
}
}
return passes;
}

int main(int argc, char* argv[]) {
//build the rules
vector<Rule> rules;
rules.push_back(Rule(2));
rules.push_back(Rule(3));
rules.push_back(Rule(5));
rules.push_back(Rule(7));
rules.push_back(Rule(11));
rules.push_back(Rule(13));
//Show three different codes that should (in my mind) take the same amount of passes over the rules but don't
cout << "Facts populated after " << doublyInefficient(rules) << " passes through the Rules." << endl;
cout << "Facts populated after " << singlyInefficient(rules) << " passes through the Rules." << endl;
cout << "Facts populated after " << efficient(rules) << " passes through the Rules." << endl;
getchar();
}

在 visual studio 2017 上以调试和 Release模式(32 位)运行时,我得到以下输出。据我所知,代码未优化。

Facts populated after 61 passes through the Rules.
Facts populated after 17 passes through the Rules.
Facts populated after 7 passes through the Rules.

最佳答案

addedFacts = addedFacts || set.insert(x).second;

if (set.insert(x).second) {
addedFacts = true;
}

绝对不是一回事。第一个代码块相当于:

if (!addedFacts) {
addedFacts = set.insert(x).second;
}

!addedFacts 检查有很大不同。

关于C++ 在 if 语句设置条件为真和 or-ing 循环条件之间的行为差​​异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45471489/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com