[英]How do I keep a head pointer in a Linked List from being reasigned when iterating through it?
[英]When iterating through a list, how do I keep track of a list element to be deleted later on?
在這個例子中,我構建了一個包含4個Person對象的鏈表 ,每個對象都有一個年齡 。 我想遍歷人員列表,跟蹤最年輕的人,然后從列表中刪除該人。
這是我到目前為止所擁有的
#include <iostream>
#include <vector>
#include <list>
struct Person
{
Person(int x): age(x) {}
int age;
};
int main() {
// Create 4 Person instances
Person p1 = Person(50);
Person p2 = Person(35);
Person p3 = Person(99);
Person p4 = Person(17);
// Build a list of persons
std::list<Person> persons = {p1, p2, p3, p4};
// Delete the list-element of the youngest person
int minAge = 999; // track the lowest age so far
Person* youngin = nullptr; // track the person with the lowest age so far
// Iterate through each person in the list, looking for someone with a lower age than all previous
for(auto const &p : persons){
if(p.age < minAge){
std::cout << "Found someone younger. Age: " << p.age << std::endl;
// Update minAge and youngin
minAge = p.age;
// youngin = ???;
}
}
// Delete the youngest person from the list
// persons.erase(youngin);
return 0;
}
我如何1)保留一個指針(我認為?)給最年輕的人“到目前為止”和2)從結尾的列表中刪除該元素?
我似乎過度簡化了我的最小可重復性示例。 @NathanOliver似乎對我提出的問題有最好的解決方案,所以我會選擇他作為被接受者,但是如果有人願意幫助我,
假設列表中沒有第5個人,
Person p5 = Person(30);
現在,如何識別列表中4個人中哪個人的年齡最接近p5
,然后從列表中刪除該人? (在這種情況下,應該識別並刪除p2
。)我沒有看到如何使用std::min_element
將Nathan的解決方案應用於這種情況。
干杯
您可以使用標准算法和lambda來完成此任務。 std::min_element
可用於查找最小元素,並且它返回的迭代器可以傳遞給列表erase
成員函數以將其從列表中刪除。 那看起來像
persons.erase(std::min_element(persons.begin(),
persons.end(),
[](auto const& lhs, auto const& rhs){ return lhs.age < rhs.age; }));
如果你需要在處理它之前使用最小值,你可以分開調用
auto min_it = std::min_element(persons.begin(),
persons.end(),
[](auto const& lhs, auto const& rhs){ return lhs.age < rhs.age; }));
//use min_it here
person.erase(min_it); // get rid of the minimum
更新:
您仍然可以使用min_element
來查找元素,我們只需要找到最小差異而不是最小元素。 我們只需要將lambda更改為比較年齡和值的差異,而不是僅僅考慮年齡。
Person p5 = Person(30);
persons.erase(std::min_element(persons.begin(),
persons.end(),
[&](auto const& lhs, auto const& rhs){
return std::abs(lhs.age - p5.age) < std::abs(rhs.age - p5.age);
}));
我在lambda中使用[&]
因此它通過引用捕獲p5
,因此我們可以計算差異。 您可以在此實例中看到它正常工作。
p
的類型是std::list<Person>::iterator
(因為它需要是一個“節點”類,在大多數情況下存儲指向下一個節點的指針和節點的值)。
std::list::erase
接受一個迭代器,而for循環取消引用迭代器,所以你沒有得到迭代器。
因此,您需要使用std::list::begin
和std::list::end
來獲取迭代器。
typename std::list<Person>::iterator youngin; // track the person with the lowest age so far
// Or:
decltype(persons.cbegin()) youngin;
// Iterate through each person in the list, looking for someone with a lower age than all previous
for (auto it = persons.cbegin(); it != persons.cend(); ++it){
if (p->age < minAge) {
std::cout << "Found someone younger. Age: " << p.age << std::endl;
// Update minAge and youngin
minAge = p->age;
youngin = it;
}
}
// Delete the youngest person from the list
persons.erase(youngin);
如果您不必使用指針,則此代碼應該:
int main() {
// Build a list of persons
std::list<Person> persons = {Person(50), Person(35), Person(99), Person(17)};
Person yongestPerson = persons[0];
// looking for someone with a lower age than all previous yongestPerson
for(persons p : persons){
if(p.age < yongestPerson.age){
std::cout << "Found someone younger. Age: " << p.age << std::endl;
// Update minAge and youngin
yongestPerson = p
}
}
// Delete the youngest person from the list
persons.remove(yongestPerson);
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.