时间限制:C/C++ 1000MS,其他语言 2000MS
内存限制:C/C++ 128MB,其他语言 256MB
难度:困难
分数:100 OI排行榜得分:16(0.1分数+2难度)
描述
将一个CSV格式的数据文件中,包含有单元格引用的内容替换为对应单元格内容的实际值。
comma separated values(CSV) 逗号分隔值,CSV格式的数据文件使用逗号","作为分符将各单元的内容进行分隔
输入描述
- 输入只有一行数据,用逗号分隔每个单元格,行尾没有逗号。最多26个单元格,对应编号A~Z.
- 每个单元格的内容包含字母和数字,以及使用"<>"分隔的单元格引用,例如
<A>表示引用第一个单元的值. - 每个单元格的内容,在替换前和替换后均不超过100个字符
- 引用单元格的位置不受限制,允许排在后面的单元格被排在前面的单元格引用
- 不存在循环引用的情况,比如下面这种场景是不存在的:
A单元格: aCde<B>8u
B单元格: kAy<A>dzqo
- 不存在多重引用<>的情况,一个单元格只能引用一个其他单元格。比如下面这种场景是不存在的:
A单元格:C
B单元格: kAydzqo
C单元格: y<A><B>d
D单元格: y<<A>>d
输出描述
输出所有单元格展开后的内容,单元格之间用",“分隔。处理过程中出现错误时,输出字符串”-1"表示出错。
用例输入 1 **
1,2<A>00
用例输出 1 **
1,2100
通过:83
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <regex>
#include <functional>
std::string replace_references(const std::string& input_str) {
// 1. Split input by comma and trim whitespace
std::vector<std::string> cells;
std::string current;
for (char c : input_str) {
if (c == ',') {
while (!current.empty() && current[0] == ' ') current.erase(0, 1);
while (!current.empty() && current.back() == ' ') current.pop_back();
cells.push_back(current);
current.clear();
} else {
current += c;
}
}
if (!current.empty()) {
while (!current.empty() && current[0] == ' ') current.erase(0, 1);
while (!current.empty() && current.back() == ' ') current.pop_back();
cells.push_back(current);
}
// 2. Create a map to store original cell values
std::unordered_map<char, std::string> cell_dict;
for (size_t i = 0; i < cells.size(); ++i) {
cell_dict['A' + i] = cells[i];
}
// 3. Define recursive function to resolve cell content
std::function<std::string*(char, std::unordered_set<char>)> resolve =
[&](char cell_name, std::unordered_set<char> visited) -> std::string* {
// Check for circular reference
if (visited.count(cell_name)) {
return nullptr; // Return nullptr for error
}
// Get current cell content
auto it = cell_dict.find(cell_name);
std::string content = (it != cell_dict.end()) ? it->second : "";
// If content is empty, return empty string
if (content.empty()) {
static std::string empty = "";
return ∅
}
// Check for reference pattern <X>
std::regex pattern("<([A-Z])>");
std::smatch match;
if (std::regex_search(content, match, pattern)) {
char ref_cell = match[1].str()[0];
// Check if referenced cell exists
if (cell_dict.find(ref_cell) == cell_dict.end()) {
return nullptr; // Referenced cell doesn't exist
}
visited.insert(cell_name);
std::string* resolved_ref = resolve(ref_cell, visited);
if(!resolved_ref){
return nullptr;
}
content.replace(match.position(), match.length(), *resolved_ref);
}
static std::string result;
result = content;
return &result;
};
std::vector<std::string> result;
for(int i = 0; i < cells.size(); ++i){
char cell = 'A' + i;
std::string* resolved_content = resolve(cell, std::unordered_set<char>());
if(!resolved_content){
return "-1";
}
result.push_back(*resolved_content);
}
std::string output;
for(int i = 0; i < result.size(); ++i){
output += result[i];
if(i != result.size() -1){
output += ",";
}
}
return output;
}
int main() {
std::string user_input;
std::getline(std::cin, user_input);
std::string output = replace_references(user_input);
std::cout << output << std::endl;
return 0;
}