我可能会对std::set工作感到困惑。我的代码无法正常工作
I might be confused about std::set works. My code isn't working right
我正在制作一个剽窃检测程序。成品将一句一句地比较两个完整的文本文件;在这一点上,我只是在测试我的算法,以便与句子进行比较,并给出一个介于0和1之间的数字来判断它们的单词有多相似。
我会尝试逐步通过代码,并向您展示问题所在。
指令和函数声明:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <math.h>
#include <set>
double sntnc_cmpr_qtnt(const std::vector<std::string>&, const std::vector<std::string>&);
main获取两个字符串数组,并将它们放入向量中。我知道这似乎没用,但这只是为了我的测试目的。我计算字符串的两个向量(应该是两个句子)之间的句子比较商。
int main (int argc, char* const argv[]) {
std::string arr1[] = {"Yo", "dawg", "I", "heard", "you", "like", "functions", "so", "we", "put", "a", "function", "inside"};
std::vector<std::string> str1, str2;
for (int i = 0; i < sizeof(arr1)/sizeof(std::string); ++i)
str1.push_back(arr1[i]);
std::string arr2[] = {"Yo", "dawg", "I", "heard", "you", "like", "cars", "so", "we", "put", "a", "car", "inside"};
for (int i = 0; i < sizeof(arr2)/sizeof(std::string); ++i)
str2.push_back(arr2[i]);
std::cout << sntnc_cmpr_qtnt(str1, str2);
return 0;
}
这是句子比较商函数。它计算两个句子之间的共同单词数。
不过出了点问题。我的计数(cnt)是158,这显然太高了。我不明白为什么。
double sntnc_cmpr_qtnt(const std::vector<std::string>& s1, const std::vector<std::string>& s2) {
// Place the words of sentences s1 and s2 each into seperate sets s1_set and s2_set:
std::set<std::string> s1set, s2set;
for (std::vector<std::string>::const_iterator it = s1.begin(); it != s1.end(); ++it)
s1set.insert(*it);
for (std::vector<std::string>::const_iterator it = s2.begin(); it != s2.end(); ++it)
s2set.insert(*it);
/* Compute the proportion of words in common between str1_set and str2_set,
multiped by 1 over 1 minus the squareroot of the size of the smaller set.
This is the sentence comparison quotient that is returned. */
double cnt(0.0);
for (std::set<std::string>::iterator it1 = s1set.begin(); it1 != s1set.end(); ++it1) {
for (std::set<std::string>::iterator it2 = s2set.begin(); it2 != s2set.end(); ++it2) {
if ((*it1).compare(*it2))
cnt += 1.0;
}
}
if (cnt == 0.0) {
return 0.0;
} else {
double minsz = (double)std::min(s1set.size(), s2set.size());
return ((1-1/sqrt(minsz))*cnt/minsz);
}
}
您可以使用==
运算符比较两个std::string
。
但你做的工作也比必要的多得多。一个更快的解决方案是将第一个列表中的所有单词放入集合中,并保存集合的大小。然后将第二个列表中的所有单词放入该集合中。最终设置的大小和保存的大小之间的差异是第二列表中不在第一列表中的单词的数量。(即唯一单词。)当然,保存的大小是第一个列表中唯一单词的数量。
类似的计算会得到第二个列表中唯一单词的数量,以及第一个列表中不在第二个名单中的单词数量。
总执行时间大致与单词总数成比例(实际上,它是n log u
,其中u
是唯一单词的数量),而您的解决方案与列表大小的乘积成比例。
主要问题在这里:
if ((*it1).compare(*it2))
cnt += 1.0;
如果它们不相等,这将增加cnt-compare返回0表示相等
此外,您还有一个集合-而不是进行内部循环,只需调用find:
for (std::set<std::string>::iterator it1 = s1set.begin(); it1 != s1set.end(); ++it1)
{
if (s2set.find(*it1) != s2set.end())
{
cnt += 1.0;
}
}
我不知道为什么cnt
应该是double而不是int
相关文章:
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 当我从下面的代码中删除关键字 virtual 时,它可以正常工作,否则会出现错误。在这里"virtual"字的意义是什么?
- C++代码在台式机上工作正常,但在笔记本电脑上则不行
- 我想使用此代码单击某个特定窗口,但它无法正常工作
- C++代码停止工作错误使用cout内部函数
- 我的代码无法正常工作。谁能指出错误?
- 有人可以详细解释这个回文代码是如何工作的吗?
- 代码在 CodeSignal 中工作不正确。不确定这是否是我的代码缺陷
- 代码在Visual Studio 2017中不起作用,但在VS代码中工作
- 以下代码如何工作以每次为唯一调用堆栈唯一实例化模板函数?
- 添加新行时工作代码引发异常.调试技巧?
- 一个非常简单的win32套接字代码,但工作错误
- 需要WXLISTCTRL的代码更改为虚拟样式WXListCtrl的工作代码
- C++ / CannyEdgeDetection.exe 已停止工作 代码块 /OpenCV 错误:断言失败
- C //尝试重写一个工作代码以包括我的功能
- 如何在不保存文件的情况下制作打印屏幕并将其发送到FTP服务器?我的工作代码将文件保存到HDD
- 如何在不破坏当前工作代码的情况下添加小数
- 无法理解工作代码和损坏代码之间的区别
- .exe已停止工作代码块 CPP
- rapidjson:用于从文件中读取文档的工作代码