#include <iostream> #include <vector> #include <algorithm> #include <unordered_set> using namespace std; vector<vector<float>> findStonePairs(const vector<float> &stones, float D) { vector<vector<float>> result; unordered_set<float> set; for (int i = 0; i < stones.size(); i++) { float target1 = stones[i] - D; if (set.count(target1)) { result.push_back(vector<float>{target1, stones[i]}); // weight } float target2 = stones[i] + D; if (set.count(target2)) { result.push_back(vector<float>{target2, stones[i]}); // weight } set.insert(stones[i]); } return result; } int main() { float d = 2; vector<float> weights_test1 = {1.2, 3.2, 1.3, 3.3, 6, 5.2}; vector<vector<float>> result_test1 = findStonePairs(weights_test1, d); cout << "test1:" << endl; for (int i = 0; i < result_test1.size(); i++) { for (int j = 0; j < result_test1[i].size(); j++) { cout << result_test1[i][j] << " "; } cout << endl; } return 1; }为什么结果与预期不同
时间: 2023-12-10 07:42:56 浏览: 27
可能是因为你在比较浮点数时使用了相等运算符,这在计算机中是不准确的。你可以使用一个足够小的数值epsilon来代替相等运算符,例如:
```
bool isEqual(float a, float b, float epsilon = 0.0001) {
return fabs(a - b) < epsilon;
}
```
然后在比较浮点数时,使用这个函数来代替相等运算符。此外,你可能还需要按照一定的顺序对石头进行排序,以便在比较时能够保证正确的结果。
相关问题
优化这段代码#include <iostream> #include <iomanip> #include <stdio.h> #include <fstream> #include <string> #include <algorithm> #include <unordered_map> #include <map> #include <stack> #include <set> #include <vector> using namespace std; struct Production { char left; // 产生式的左部非终结符 string right; // 产生式的右部字符串 }; map<char, set<char>> firstSets; int main() { vector<Production> productions; ifstream infile("grammar.txt"); char left; string right; while (infile >> left >> right) { productions.push_back({ left, right }); } for (auto p : productions) { char left = p.left; string right = p.right; char firstChar = right[0]; if (isupper(firstChar)) { // 如果是非终结符 // 计算非终结符的first集合 set<char> firstSet = firstSets[firstChar]; for (int i = 0; i < right.length(); i++) { char ch = right[i]; if (isupper(ch)) { // 如果是非终结符 firstSet.insert(firstSets[ch].begin(), firstSets[ch].end()); if (firstSets[ch].find('$') == firstSets[ch].end()) { // 如果该非终结符没有空串 break; } } else { // 如果是终结符 firstSet.insert(ch); break; } } firstSets[left].insert(firstSet.begin(), firstSet.end()); } else { // 如果是终结符 firstSets[left].insert(firstChar); } } for (auto p : productions) { char left = p.left; cout << "First(" << left << ") = {"; for (auto ch : firstSets[left]) { cout << ch << ", "; } cout << "}" << endl; } }使得能正确求出frist集
以下是优化后的代码:
```c++
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <set>
using namespace std;
// 产生式结构体
struct Production {
char left; // 产生式的左部非终结符
string right; // 产生式的右部字符串
};
// 计算first集合
set<char> calcFirstSet(char ch, const vector<Production>& productions, map<char, set<char>>& firstSets) {
// 如果该字符已经计算过first集合,直接返回
if (firstSets.find(ch) != firstSets.end()) {
return firstSets[ch];
}
set<char> result;
// 遍历所有产生式,查找该字符作为左部的产生式
for (auto p : productions) {
if (p.left == ch) {
// 如果右部第一个字符是终结符,则加入该字符
if (!isupper(p.right[0])) {
result.insert(p.right[0]);
}
// 如果右部第一个字符是非终结符,则计算该非终结符的first集合
else {
set<char> subResult = calcFirstSet(p.right[0], productions, firstSets);
result.insert(subResult.begin(), subResult.end());
// 如果该非终结符的first集合中包含空串,则计算下一个字符的first集合
for (int i = 1; i < p.right.length() && subResult.find('$') != subResult.end(); i++) {
if (!isupper(p.right[i])) {
result.insert(p.right[i]);
break;
} else {
subResult = calcFirstSet(p.right[i], productions, firstSets);
result.insert(subResult.begin(), subResult.end());
}
}
}
}
}
// 将计算得到的first集合插入到map中
firstSets.insert(make_pair(ch, result));
return result;
}
int main() {
vector<Production> productions;
ifstream infile("grammar.txt");
// 读取产生式
char left;
string right;
while (infile >> left >> right) {
productions.push_back({ left, right });
}
map<char, set<char>> firstSets;
// 计算每个非终结符的first集合
for (auto p : productions) {
if (isupper(p.right[0])) {
set<char> result = calcFirstSet(p.left, productions, firstSets);
firstSets.insert(make_pair(p.left, result));
} else {
firstSets.insert(make_pair(p.left, set<char>{p.right[0]}));
}
}
// 输出每个非终结符的first集合
for (auto p : productions) {
char left = p.left;
cout << "First(" << left << ") = {";
for (auto ch : firstSets[left]) {
cout << ch << ", ";
}
cout << "}" << endl;
}
}
```
优化后的代码主要是将计算first集合的部分提取出来,封装成了一个函数`calcFirstSet`。在计算每个非终结符的first集合时,只需调用该函数进行计算即可。同时,在计算非终结符的first集合时,使用了递归的方式,可以很方便地计算出包含空串的情况。
优化#include <iostream>#include <string>#include <vector>#include <algorithm>using namespace std;int main() { string code1 = "int main() {int a = 1; float b = 2.0; while(a < 10) {a++; if(a == 5) break;} return 0;}"; string code2 = "int main() {double x = 3.0; int y = 4; for(int i = 0; i < y; i++) {if(i % 2 == 0) continue; y--;}}"; vector<string> segments = {"{int a = 1", "while(a < 10)", "if(a == 5)", "int y = 4;", "for(int i = 0;", "if(i % 2 == 0)"}; int count = 0; for (int i = 0; i < segments.size(); i++) { if (code2.find(segments[i]) != string::npos) { count++; } } double plagiarism = (double)count / (double)segments.size(); cout << "抄袭概率:" << plagiarism << endl; if (plagiarism > 0.5) { cout << "可能存在抄袭行为!" << endl; } else { cout << "不存在抄袭行为。" << endl; } return 0;}
这段代码中可以进行一些优化:
1. 在使用 vector 存储子串的时候,可以使用常量数组来代替,这样可以节省一些内存空间。
2. 在循环中使用迭代器来遍历 vector,这样可以提高程序的效率。
3. 在判断子串是否存在的时候,可以使用 unordered_set 来代替 vector,这样可以更快地进行查找操作。
4. 在输出抄袭概率的时候,可以将小数点后面的数字格式化为固定位数,这样可以更加美观。
下面是优化后的代码:
#include <iostream>
#include <string>
#include <unordered_set>
using namespace std;
int main() {
string code1 = "int main() {int a = 1; float b = 2.0; while(a < 10) {a++; if(a == 5) break;} return 0;}";
string code2 = "int main() {double x = 3.0; int y = 4; for(int i = 0; i < y; i++) {if(i % 2 == 0) continue; y--;}}";
const string segments[] = {"{int a = 1", "while(a < 10)", "if(a == 5)", "int y = 4;", "for(int i = 0;", "if(i % 2 == 0)"};
int count = 0;
unordered_set<string> segmentSet(segments, segments + 6);
for (auto it = segmentSet.begin(); it != segmentSet.end(); ++it) {
if (code2.find(*it) != string::npos) {
count++;
}
}
double plagiarism = (double)count / 6.0;
cout.precision(3); // 设置输出小数点后三位
cout << "抄袭概率:" << fixed << plagiarism << endl;
if (plagiarism > 0.5) {
cout << "可能存在抄袭行为!" << endl;
} else {
cout << "不存在抄袭行为。" << endl;
}
return 0;
}