面试题答案
一键面试一、数据结构设计
- 文本数据存储
- 使用
std::vector<std::string>
来存储文本行,因为vector
可以动态扩展,适合处理海量文本数据。
std::vector<std::string> textLines;
- 使用
- 子串频率统计
- 使用
std::unordered_map<std::string, int>
来统计不同子串出现的频率。unordered_map
的查找和插入操作平均时间复杂度为O(1),适合高效的频率统计。
std::unordered_map<std::string, int> substringFrequency;
- 使用
- 查找结果存储
- 设计一个结构体来存储查找到的结果,包括文本行的索引和子串在该行中的位置。
struct FindResult { int lineIndex; std::vector<size_t> positions; }; std::vector<FindResult> findResults;
二、接口设计
- 初始化接口
- 用于将文本数据加载到内存中。
void initialize(const std::string& filePath) { std::ifstream file(filePath); std::string line; while (std::getline(file, line)) { textLines.push_back(line); } }
- 模糊查找接口
- 接收一个子串作为参数,在文本中进行模糊查找,并返回查找结果。
std::vector<FindResult> fuzzyFind(const std::string& substring) { std::vector<FindResult> results; for (size_t i = 0; i < textLines.size(); ++i) { std::string line = textLines[i]; size_t pos = line.find(substring); if (pos!= std::string::npos) { FindResult result; result.lineIndex = static_cast<int>(i); while (pos!= std::string::npos) { result.positions.push_back(pos); pos = line.find(substring, pos + 1); } results.push_back(result); substringFrequency[substring]++; } } return results; }
- 修改文本接口
- 根据查找结果修改文本内容。
void modifyText(const std::vector<FindResult>& results, const std::string& newSubstring) { for (const auto& result : results) { std::string& line = textLines[result.lineIndex]; for (size_t pos : result.positions) { line.replace(pos, newSubstring.length(), newSubstring); } } }
- 获取子串频率接口
- 返回特定子串的出现频率。
int getSubstringFrequency(const std::string& substring) { auto it = substringFrequency.find(substring); if (it!= substringFrequency.end()) { return it->second; } return 0; }
三、异常处理机制
- 文件读取异常
- 在
initialize
函数中,使用try - catch
块捕获std::ifstream
可能抛出的异常,如文件不存在等。
void initialize(const std::string& filePath) { try { std::ifstream file(filePath); std::string line; while (std::getline(file, line)) { textLines.push_back(line); } } catch (const std::ifstream::failure& e) { std::cerr << "Error opening file: " << e.what() << std::endl; // 可以根据需求进行更详细的处理,如抛出自定义异常 } }
- 在
- 其他潜在异常
- 在
fuzzyFind
函数中,find
操作本身不会抛出异常,但如果substring
为空,可能会导致未定义行为,所以可以在函数开头添加参数检查。
std::vector<FindResult> fuzzyFind(const std::string& substring) { if (substring.empty()) { throw std::invalid_argument("Substring cannot be empty"); } // 后续查找逻辑 }
- 在
modifyText
函数中,确保newSubstring
的长度合理,避免修改文本时导致缓冲区溢出等问题。同样可以通过参数检查和抛出std::invalid_argument
异常来处理。
void modifyText(const std::vector<FindResult>& results, const std::string& newSubstring) { if (newSubstring.length() > 1024) { // 假设最大长度限制为1024,可根据实际调整 throw std::invalid_argument("New substring length is too large"); } // 后续修改逻辑 }
- 在