- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下代码片段,用于将元素插入集合并检索它们。但是正如您从示例输出中看到的那样,学生 1 的名字(即“stud1”)并没有被打印出来,即使它是按到达时间排序的。任何人都可以帮助找出这种方法有什么问题吗?
#ifndef Student_h
#define Student_h
#include "string"
class Student
{
public:
Student();
~Student();
void setName(const std::string& p_name) { _name = p_name; }
void setArrivalTime(const int p_arr_t) { _arrivalTime = p_arr_t; }
const std::string& getName() const { return _name; }
const int getArrivalTime() const { return _arrivalTime; }
private:
std::string _name;
int _arrivalTime;
};
struct CompareStudByArrivaltime
{
const bool operator()(const Student* s1, const Student* s2) const;
};
#endif /* Student_h */
#include <stdio.h>
#include "Student.h"
Student::Student()
{
}
Student::~Student()
{
}
const bool CompareStudByArrivaltime::operator()(const Student* s1, const Student* s2) const
{
if (s1->getName() == s2->getName())
{
return false;
}
return (s1->getArrivalTime() <= s2->getArrivalTime());
}
#include <iostream>
#include <set>
#include <map>
#include <vector>
#include "Student.h"
typedef std::vector<Student> StudentsPool;
typedef std::set<Student*, CompareStudByArrivaltime> Students;
typedef std::map<std::string,Students> SchoolStudentsMap;
SchoolStudentsMap g_school_studs;
StudentsPool g_stud_pool;
Student* getStud(const std::string& n)
{
for(StudentsPool::iterator itr = g_stud_pool.begin(); itr != g_stud_pool.end(); ++itr)
{
if (itr->getName() == n)
{
return &(*itr);
}
}
return NULL;
}
void initObj()
{
/** School 1 Record */
std::string school_name = "school1";
char c1 [] = {'s','t','u','d','1','\0'};
std::string n1(c1);
//Student* s1 = new Student();
Student s1;
s1.setName(n1);
s1.setArrivalTime(10);
g_stud_pool.push_back(s1);
Student* tmp = NULL;
tmp = getStud("stud1");
g_school_studs[school_name].insert(tmp);
char c2 [] = {'s','t','u','d','2','\0'};
std::string n2(c2);
Student s2;
s2.setName(n2);
s2.setArrivalTime(2);
g_stud_pool.push_back(s2);
tmp = getStud("stud2");
g_school_studs[school_name].insert(tmp);
char c3 [] = {'s','t','u','d','3','\0'};
std::string n3(c3);
Student s3;
s3.setName(n3);
s3.setArrivalTime(5);
g_stud_pool.push_back(s3);
tmp = getStud("stud3");
g_school_studs[school_name].insert(tmp);
}
void processObj()
{
for(SchoolStudentsMap::iterator itr = g_school_studs.begin(); itr != g_school_studs.end(); ++itr)
{
Students& studs = itr->second;
for(Students::iterator sitr = studs.begin(); sitr != studs.end(); ++sitr)
{
Student* s = (*sitr);
std::cerr << "Name: " << s->getName() << ", Arr Time: " << s->getArrivalTime() << std::endl;
}
}
}
int main(int argc, const char * argv[])
{
initObj();
processObj();
return 0;
}
Name: stud2, Arr Time: 2
Name: stud3, Arr Time: 5
Name: , Arr Time: 10
最佳答案
看你的比较函数。如果到达时间相同,但元素的顺序不同,您将返回 true
。
const bool CompareStudByArrivaltime::operator()(const Student* s1, const Student* s2) const
{
if (s1->getName() == s2->getName())
{
return false;
}
return (s1->getArrivalTime() <= s2->getArrivalTime());
// what if s1 and s2 are equal, but switched? You still return true.
}
假设s1和s2到达时间相同。您的函数返回 true
。那么假设我们调用了您的比较函数,但这次使用的是 s2 和 s1。您仍然返回 true
。怎么可能?怎么能说s1放在s2之前的容器中,然后同时s2应该放在s1之前的容器中呢?编译器问你哪个先出现,当项目相等时你给出了不可能的答案。这就是 std::set
排序标准变得困惑并最终为您提供错误结果的地方。
简而言之,这就是严格弱排序的全部内容,@Slava 给出了解决方案的详细信息。
顺便说一句,切换项目和检查返回值的测试是由调试 Visual C++ 运行时完成的。您的代码可能会立即断言,因为运行时调用排序例程两次,第一次使用 s1, s2
,然后使用 s2, s1
。如果您为这两种情况返回 true
,运行时将中止您的应用程序。
另一个问题是您将指向项目的指针存储在此处的 Student
vector 中:
g_stud_pool.push_back(s1);
tmp = getStud("stud1"); // <-- gets pointer to item just placed in g_stud_pool
g_school_studs[school_name].insert(tmp); // <-- pointer to Student from the vector being stored
//...
g_stud_pool.push_back(s2); // <-- invalidates previous pointer
tmp = getStud("stud2");
g_school_studs[school_name].insert(tmp); // <-- map now contains invalid pointer(s)
您正在向 g_stud_pool
vector 中添加项目,然后立即使用指向您刚刚放置在 vector 中的项目的指针,通过将该指针放置在您的 std::set 中来引用该项目
。
问题在于,每次向 vector 添加一个项目时,指向先前项目的任何指针都可能失效。最终发生的是您的 set
使用的比较函数将使用已失效的地址。
解决此问题的最快方法(不是唯一方法)是更改为在调整大小时不会使指针(和迭代器)失效的容器。这样的容器就是 std::list
。所以改成这样:
#include <list>
typedef std::list<Student> StudentsPool;
解决了失效问题,因为 std::list
在调整列表大小时不会使指针和迭代器失效。
关于c++ - 自定义比较器以将唯一元素插入到 C++ 中的集合中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36481407/
在开发中的网页上,我在 IE 上遇到此错误 element = $(element); 此代码位于prototype.js 预期对象 如何消除此错误。 更新: 现场也使用了 jQuery。 最佳答
我有两个大小相同的嵌套数组: Array1 =[[1, 2], [], [2, 3]] Array2= [[1, 4], [8, 11], [3, 6]] 我需要将它们合并到一个数组中,如下所示: A
我有一些 jQuery 代码,当单击具有特定 ID 的项目时运行。当 ID 是 的一部分时,它就可以工作。元素,但当它位于 中时则不然元素。为什么会这样呢?我想使用 an,因为如果用户关闭了 Ja
Flex-box 规范 3声明 flex 元素不是 block 容器: A flex item establishes a new formatting context for its content
我遇到了一个意想不到的问题。 HTML JS $(function() { var $divs = $('.myDiv'); // create new div not in
我使用 Bootstrap 和 Ember.js 得到了一个无序列表。每个列表项都是一个显示新帖子的链接,每当您单击该链接时,Ember 都会添加类 active默认情况下。我正在使用 Bootstr
我正在尝试让一个函数正常工作,但运气不佳,所以我想向 Stackoverflow 智囊团提出一个新手问题! 基本上,我有一个表单,并且循环遍历所有元素以查看是否存在自定义数据属性。如果存在,则保持该元
我想映射一个可选数组,删除那些 nil 值,并使用另一个函数映射非 nil 值。 我知道我可以通过使用 compactMap 然后使用常规 map 来实现这一点,但我只想遍历数组一次。 我为此实现了一
我如何定位 li 元素,除非它们出现在 之后元素?换句话说,我想针对步骤而不是注释。 我尝试向 OL 添加一个我想从选择中排除的类,但我想出的代码不起作用。 (顺便说一句,重构 html 不是一种选
Warning 1 The element 'system.webServer' has invalid child element 'rewrite'. List of possible eleme
我正在尝试编写一个脚本,该脚本将遍历 HTML 源并创建 DOM 的 JSON 文件,然后使用 d3.js 在 TreeView 中显示该文件。我遇到的问题是不仅希望显示元素(TITLE、P、LI 等
我有以下 HTML 表单:- Option 1 Option 2
我试图在选定的 HTML 元素之后选择下一个具有类名 slider-value 的 span 元素。我尝试了多种解决方案,但没有一个有效。 我可以通过 id 选择它,但我不希望那样做使代码冗余。 $(
如果电子邮件地址无效,我想在屏幕上显示一条消息“请输入有效的电子邮件地址”。 body 元素的innerHTML 语句工作正常,但我用于p 元素的innerHTML 语句不起作用。 有一次,当我测试它
以下 jQuery 代码调用 ul 元素,查找元素内的前 三个 li 列表项,并隐藏剩余的 li 项目。然后,它附加一个 li 元素,其中显示“显示更多...”,并且在单击时显示之前隐藏的列表项。 (
我问了a question早些时候关于将编辑/删除链接与 h1 元素内联的最佳方法。我能够通过给出的答案实现这一点,但我现在有额外的要求,我需要在 h1 下方显示一个段落并编辑/删除链接。 到目前为止
我使用 MVC 4 和 knockout.js 库版本 2.1.0 显示从服务器检索到的大量文件的表中的以下摘录。 0)"> 正在正确检索数据,
我创建了一个脚本,该脚本在鼠标悬停在父容器上时激活,并且应该将其子元素移离鼠标。我目前已经让它工作了,但是代码的某些部分似乎与 REACT 代码应该是什么样子相矛盾。特别是两个部分。 我在渲染函数中使
我是 JS 新手,正在尝试理解项目 https://github.com/tastejs/todomvc 的代码 请参阅屏幕截图,我尝试对 button X 以及其父元素 div 设置断点,但在这两种
例如,假设有一个带有奇特颜色的标记: Something written here 使用 Visual Studio 2017 和 MVC 5 元素,有没有办法检查和定位当前应用了哪些样式,以及负责它
我是一名优秀的程序员,十分优秀!