C++ Plagiarism Check
#include <algorithm>
#include <cctype>
#include <regex>
#include <string>
#include <unordered_map>
#include <vector>
bool plagiarismCheck(const std::vector<std::string>& code1, const std::vector<std::string>& code2)
{
auto join = [](const std::vector<std::string>& lines) {
std::string result;
for (std::size_t i = 0; i < lines.size(); ++i) {
if (i > 0) {
result += ' ';
}
result += lines[i];
}
return result;
};
std::string c1 = join(code1);
std::string c2 = join(code2);
if (c1 == c2) {
return false;
}
std::vector<std::string> d1;
std::vector<std::string> d2;
std::regex wordRe(R"(\w+)");
for (auto it = std::sregex_iterator(c1.begin(), c1.end(), wordRe); it != std::sregex_iterator(); ++it) {
d1.push_back(it->str());
}
for (auto it = std::sregex_iterator(c2.begin(), c2.end(), wordRe); it != std::sregex_iterator(); ++it) {
d2.push_back(it->str());
}
std::unordered_map<std::string, std::string> rCand;
for (std::size_t k = 0; k < d1.size() && k < d2.size(); ++k) {
bool isNumeric = !d1[k].empty() && std::all_of(d1[k].begin(), d1[k].end(), [](unsigned char c) { return std::isdigit(c); });
if (d1[k] != d2[k] && !isNumeric) {
rCand[d1[k]] = d2[k];
}
}
for (const auto& [orig, repl] : rCand) {
c1 = std::regex_replace(c1, std::regex("(\\W)" + orig + "(\\W*)"), "$1PLACEHOLDER" + orig + "$2");
c1 = std::regex_replace(c1, std::regex("(\\W)" + orig), "$1PLACEHOLDER" + orig);
}
for (const auto& [orig, repl] : rCand) {
c1 = std::regex_replace(c1, std::regex("(\\W)PLACEHOLDER" + orig + "(\\W)"), "$1" + repl + "$2");
c1 = std::regex_replace(c1, std::regex("(\\W)PLACEHOLDER" + orig), "$1" + repl);
}
return c1 == c2;
}
This flattens both snippets, tries consistent identifier replacements, and checks whether the rewritten code matches.