C++ 聊天机器人:基于语料库的智能问答系统
以下是一个简单的 C++ 实现,可以根据用户输入的问题,在语料库中寻找匹配程度最高的问题,并输出相应的回答。同时,它还可以根据用户的输入进行句子断句,并输出对应的回答。
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
// 定义语料库文件名
const std::string CORPUS_FILE = "config.ini";
// 定义句子分隔符
const std::string DELIMITERS = ".,";
// 去除字符串两端的空格
std::string trim(const std::string& str) {
size_t start = str.find_first_not_of("
");
size_t end = str.find_last_not_of("
");
return (start == std::string::npos || end == std::string::npos) ? "" : str.substr(start, end - start + 1);
}
// 将字符串转换为小写
std::string toLower(const std::string& str) {
std::string result = str;
std::transform(result.begin(), result.end(), result.begin(), ::tolower);
return result;
}
// 加载语料库
std::vector<std::pair<std::string, std::string>> loadCorpus() {
std::vector<std::pair<std::string, std::string>> corpus;
std::ifstream file(CORPUS_FILE);
std::string line;
while (std::getline(file, line)) {
size_t pos = line.find('=');
if (pos != std::string::npos) {
std::string question = trim(line.substr(0, pos));
std::string answer = trim(line.substr(pos + 1));
corpus.push_back(std::make_pair(toLower(question), answer));
}
}
file.close();
return corpus;
}
// 计算字符串相似度(编辑距离)
int calculateSimilarity(const std::string& str1, const std::string& str2) {
int len1 = str1.length();
int len2 = str2.length();
std::vector<std::vector<int>> dp(len1 + 1, std::vector<int>(len2 + 1, 0));
for (int i = 0; i <= len1; ++i) {
dp[i][0] = i;
}
for (int j = 0; j <= len2; ++j) {
dp[0][j] = j;
}
for (int i = 1; i <= len1; ++i) {
for (int j = 1; j <= len2; ++j) {
if (str1[i - 1] == str2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = std::min({dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + 1});
}
}
}
return dp[len1][len2];
}
// 根据用户输入的问题,寻找匹配程度最高的问题,并返回对应的回答
std::string findBestMatch(const std::string& question, const std::vector<std::pair<std::string, std::string>>& corpus) {
int minDistance = INT_MAX;
std::string bestMatch;
for (const auto& pair : corpus) {
int distance = calculateSimilarity(question, pair.first);
if (distance < minDistance) {
minDistance = distance;
bestMatch = pair.second;
}
}
return bestMatch;
}
int main() {
// 加载语料库
std::vector<std::pair<std::string, std::string>> corpus = loadCorpus();
// 接收用户输入
std::string input;
std::cout << "请输入您的问题(以句号或逗号分隔):";
std::getline(std::cin, input);
// 断句并输出回答
std::string delimiter = ".,";
size_t pos = 0;
std::string token;
while ((pos = input.find_first_of(delimiter)) != std::string::npos) {
token = input.substr(0, pos);
std::string question = toLower(trim(token));
std::string answer = findBestMatch(question, corpus);
std::cout << "回答:" << answer << std::endl;
input.erase(0, pos + 1);
}
std::string question = toLower(trim(input));
std::string answer = findBestMatch(question, corpus);
std::cout << "回答:" << answer << std::endl;
return 0;
}
请注意,上述代码假设config.ini文件中的语料库格式为'问题=回答',并且问题和回答中不包含等号'='。在实际应用中,您需要根据自己的语料库格式进行相应的修改。
原文地址: https://www.cveoy.top/t/topic/nAr 著作权归作者所有。请勿转载和采集!