class DSU { public: std::unordered_map<std::st...
생성일: 2026년 9월 9일
답변에 사용된 모델 GPT-5.6 Thinking by Chat01
생성일: 2026년 9월 9일
답변에 사용된 모델 GPT-5.6 Thinking by Chat01
class DSU {
public:
std::unordered_map<std::string, std::string> parent;
std::unordered_map<std::string, int> rank;
textvoid add(const std::string& x) { if (!parent.count(x)) { parent[x] = x; rank[x] = 0; } } std::string find(const std::string& x) { auto it = parent.find(x); if (it == parent.end()) { add(x); return x; } if (parent[x] != x) { parent[x] = find(parent[x]); } return parent[x]; } void unite(const std::string& a, const std::string& b) { add(a); add(b); std::string ra = find(a); std::string rb = find(b); if (ra == rb) return; if (rank[ra] < rank[rb]) std::swap(ra, rb); parent[rb] = ra; if (rank[ra] == rank[rb]) ++rank[ra]; }
};
std::unordered_map<std::string, int> historyByAccount;
for (const auto& profile : profiles) {
historyByAccount[profile.account_id] = profile.return_history_count;
}
DSU dsu;
for (const auto& link : links) {
dsu.unite(link.primary_account_id,
link.related_account_id);
}
for (const auto& profile : profiles)
dsu.add(profile.account_id);
std::unordered_map<std::string, int> componentHistory;
for (const auto& [accountId, count] : historyByAccount) {
componentHistory[dsu.find(accountId)] += count;
}
dsu.add(request.account_id);
int aggregateReturnHistory = 0;
std::string root = dsu.find(request.account_id);
auto it = componentHistory.find(root);
if (it != componentHistory.end()) {
aggregateReturnHistory = it->second;
}
int calculatePoints(
double value,
const ScoringRule& rule)
{
for (const auto& range : rule.ranges) {
if (value >= range.min && value <= range.max) {
return range.points;
}
}
return 0;
}
int totalScore = 0;
for (const auto& rule : scoringRules) {
double value = 0;
textif (rule.rule == "return_history_count") { value = aggregateReturnHistory; } else if (rule.rule == "account_age_days") { value = request.account_age_days; } else if (rule.rule == "order_value_usd") { value = request.order_value_usd; } totalScore += calculatePoints(value, rule);
}
int riskScore = std::clamp(totalScore, 0, 100);
adjust this code according to the int main in c++, and do not change any line of code in int main
Yes. Based on the main() in your screenshots, you should not put the DSU/scoring code inside main(). main() already expects this interface:
cppreturns::Engine::build( category_rules, scoring_rules, decision_bands, profiles, links ); engine.evaluate(requests);
So the account-link aggregation and scoring logic should live inside returns::Engine.
Keep your int main(...) exactly as it is.
main()For example, near the top of your engine.cpp:
cpp#include <algorithm> #include <string> #include <unordered_map> #include <utility> #include <vector> namespace returns { class DSU { public: std::unordered_map<std::string, std::string> parent; std::unordered_map<std::string, int> rank; void add(const std::string& x) { if (!parent.count(x)) { parent[x] = x; rank[x] = 0; } } std::string find(const std::string& x) { auto it = parent.find(x); if (it == parent.end()) { add(x); return x; } if (parent[x] != x) { parent[x] = find(parent[x]); } return parent[x]; } void unite(const std::string& a, const std::string& b) { add(a); add(b); std::string ra = find(a); std::string rb = find(b); if (ra == rb) { return; } if (rank[ra] < rank[rb]) { std::swap(ra, rb); } parent[rb] = ra; if (rank[ra] == rank[rb]) { ++rank[ra]; } } };
calculatePoints() outside main() toocppint calculatePoints( double value, const ScoringRule& rule) { for (const auto& range : rule.ranges) { if (value >= range.min && value <= range.max) { return range.points; } } return 0; }
Engine::build()Your main() passes these five objects:
cppcategory_rules scoring_rules decision_bands profiles links
Therefore your Engine needs to retain them.
Conceptually your Engine should look like this:
cppclass Engine { public: static Engine build( const std::vector<CategoryRule>& category_rules, const std::vector<ScoringRule>& scoring_rules, const std::vector<DecisionBand>& decision_bands, const std::vector<AccountProfile>& profiles, const std::vector<AccountLink>& links); std::vector<RoutingResult> evaluate( const std::vector<ReturnRequest>& requests); private: std::vector<CategoryRule> category_rules_; std::vector<ScoringRule> scoring_rules_; std::vector<DecisionBand> decision_bands_; std::vector<AccountProfile> profiles_; std::vector<AccountLink> links_; };
Then implement build() like this:
cppEngine Engine::build( const std::vector<CategoryRule>& category_rules, const std::vector<ScoringRule>& scoring_rules, const std::vector<DecisionBand>& decision_bands, const std::vector<AccountProfile>& profiles, const std::vector<AccountLink>& links) { Engine engine; engine.category_rules_ = category_rules; engine.scoring_rules_ = scoring_rules; engine.decision_bands_ = decision_bands; engine.profiles_ = profiles; engine.links_ = links; return engine; }
This matches this line from your existing main():
cppauto engine: Engine = returns::Engine::build( category_rules, scoring_rules, decision_bands, profiles, links );
The auto engine: Engine / path: text visible in the screenshot appears to be IDE inlay/type hints, not actual C++ syntax.
Engine::evaluate()This is the important adjustment to the code you posted.
cppstd::vector<RoutingResult> Engine::evaluate( const std::vector<ReturnRequest>& requests) { std::vector<RoutingResult> results; /* * Build account -> return history lookup. */ std::unordered_map<std::string, int> historyByAccount; for (const auto& profile : profiles_) { historyByAccount[profile.account_id] = profile.return_history_count; } /* * Build linked-account groups. */ DSU dsu; for (const auto& link : links_) { dsu.unite( link.primary_account_id, link.related_account_id ); } /* * Profiles may exist without any links, * so make sure every profile is also * registered with the DSU. */ for (const auto& profile : profiles_) { dsu.add(profile.account_id); } /* * Calculate combined return history * for each linked-account component. */ std::unordered_map<std::string, int> componentHistory; for (const auto& [accountId, count] : historyByAccount) { std::string root = dsu.find(accountId); componentHistory[root] += count; } /* * Evaluate every request. */ for (const auto& request : requests) { int aggregateReturnHistory = 0; /* * Add request account if it does not * occur in profiles or links. */ dsu.add(request.account_id); std::string root = dsu.find(request.account_id); auto historyIt = componentHistory.find(root); if (historyIt != componentHistory.end()) { aggregateReturnHistory = historyIt->second; } /* * Calculate risk score. */ int totalScore = 0; for (const auto& rule : scoring_rules_) { double value = 0.0; if (rule.rule == "return_history_count") { value = static_cast<double>( aggregateReturnHistory ); } else if (rule.rule == "account_age_days") { value = static_cast<double>( request.account_age_days ); } else if (rule.rule == "order_value_usd") { value = request.order_value_usd; } else { /* * Unknown scoring rule. * Ignore it. */ continue; } totalScore += calculatePoints(value, rule); } int riskScore = std::clamp(totalScore, 0, 100); /* * ------------------------------------------------- * Your category / decision-band / RoutingResult * logic goes here. * ------------------------------------------------- * * Use: * * request * riskScore * category_rules_ * decision_bands_ * * to construct RoutingResult. */ } return results; }
Your original code had:
cppfor (const auto& profile : profiles)
and:
cppfor (const auto& link : links)
and:
cppfor (const auto& rule : scoringRules)
Those variables exist only in main(). The Engine does not automatically have access to local variables belonging to main().
Because main() does:
cppreturns::Engine::build( category_rules, scoring_rules, decision_bands, profiles, links );
the engine should save those values as members:
cppprofiles_ links_ scoring_rules_ category_rules_ decision_bands_
Then inside evaluate() you use:
cppfor (const auto& profile : profiles_)
instead of:
cppfor (const auto& profile : profiles)
Similarly:
cppfor (const auto& link : links_)
instead of:
cppfor (const auto& link : links)
and:
cppfor (const auto& rule : scoring_rules_)
instead of:
cppfor (const auto& rule : scoringRules)
So your flow becomes:
textmain() | | read_category_rules() | read_scoring_rules() | read_decision_bands() | read_account_profiles() | read_account_links() | read_return_requests() | v Engine::build(...) | | stores profiles | stores links | stores scoring rules | v Engine::evaluate(requests) | +--> build DSU | +--> connect related accounts | +--> sum return_history_count | +--> evaluate each request | +--> calculate scoring points | +--> clamp score to 0-100 | +--> determine decision band | v vector<RoutingResult> | v main() | v write_results(...)
One other thing I would not do is move this:
cppstd::unordered_map<std::string, int> historyByAccount;
into main(). Your current main() is already nicely acting as an I/O/orchestration layer, and the DSU/business logic belongs in Engine.
The next useful step is to paste your Engine class/header, RoutingResult, DecisionBand, and CategoryRule definitions. I can then fill in the final missing RoutingResult section so the whole implementation compiles without changing a single line of the main() shown in your photos.