【问题标题】:How to get the min value of an object in a list (C++)如何获取列表中对象的最小值(C++)
【发布时间】:2012-10-31 17:17:55
【问题描述】:

我有一个问题要问。

所以,我有一个结构调用 Node 如下所示:

struct Node
{
    int xKoor, yKoor;

    Node *parent;                                                                   
    char nodeId;                                                                    

    float G;
    float H;
    float F;

    Node(int x, int y, int id, Node * par)
    {
        xKoor = x;
        yKoor = y;
        nodeId = id;
        parent = 0;
    }

    Node(int x, int y, char id)                                                     
    {
        xKoor = x;
        yKoor = y;
        nodeId = id;
    }
};

我有一个包含此结构元素的列表:

list<Node*> OPEN;

此列表的大小随时间而变化。

我需要做的是找到具有最小F值的Node对象,然后从列表中弹出该对象。

所以,我试着写了一个如下所示的函数:

void enKucukFliNodeBul(list<Node*> OPEN)
{

    list<Node*>::iterator it = OPEN.begin();

    for(it = OPEN.begin(); it != OPEN.end(); it++)
    {
        if(it._Ptr->_Myval->F < it._Ptr->_Next->_Myval->F)
        {

        }
    }
}

但我被困住了。我是 STL 的新手。我该如何解决这个问题?

我最好的问候...

【问题讨论】:

  • (*it)-&gt;F 而不是 it._Ptr-&gt;_Myval-&gt;F。你需要2个迭代器。就像您正在遍历一维数组 - 使用迭代器获取当前位置和一个 - 用于下一个。或者相反。
  • 不要担心 STL、C++ 或类似的东西。首先用伪代码制定算法,甚至,天堂禁止,流程图......
  • 拜托!不要使用内部实现细节!将标准库中以下划线开头的任何内容视为不存在。它们不是界面的一部分。 (如果代码甚至可以编译,我会感到惊讶)
  • @R.MartinhoFernandes 您好,先生,我真的不明白您的意思。
  • BTW 为什么要将链接节点存储在std::list 中?它已经是一个链表,所以你在做什么似乎有点奇怪。

标签: c++ search stl


【解决方案1】:

您可以使用std::min_element 与合适的比较功能。

bool nodeComp(const Node* lhs, const Node* rhs) {
  return lhs->F < rhs->F;
}


#include <algorithm> // for std::min_element

list<Node*>::iterator it = std::min_element(OPEN.begin(), OPEN.end(), nodeComp);

这里假设list&lt;Node*&gt;std::list&lt;Node*&gt;,在这种情况下你应该知道std::list 本身就是一个链表。

其他有用的操作,基于您的 cmets:

从列表中移除一个最小值节点并将其删除:

OPEN.erase(it);
delete *it; //

如果您的节点相互依赖,您可能需要执行其他操作。

对列表进行排序:

OPEN.sort(nodeComp);

【讨论】:

  • 嗨,如果删除'it',它会从列表中弹出吗?如果是这样,我只需要说 delete *it?
  • @Un_NatMenDim 您还需要使用std::list::erase 的第一个版本将其从列表中删除。如果你只是删除它,列表将包含一个指向某个无法使用的内存位置的指针。
  • 先生还有一个问题,是否可以按 F 的最小值对列表进行排序?所以起始元素的 F 值最小。
  • @Un_NatMenDim std::list 有一个采用比较器的排序方法:OPEN.sort(nodeComp)
  • 谢谢,非常感谢。
【解决方案2】:

使用std::min_element算法和重载比较函数

bool compareF(Node *lhs, Node *rhs) 
{
 return lhs->F < rhs->F; 
}

如果您使用的是 C++03:

std::<Node*>::itertor ter = std::min_element(OPEN.begin(),OPEN.end(), compareF);

如果您使用的是 C++11:

auto iter = std::min_element(OPEN.begin(),OPEN.end(), compareF);

要对列表进行排序,您可以调用OPEN.sort(compareF); 使用compareF 函数对列表进行排序

【讨论】:

  • 感谢您的回答。如何从列表中删除 iter 并添加到另一个列表?
  • 不需要删除iter
  • 我想在找到最小值后从列表中删除它。
  • 哦,使用 std::remove 和 std::erase 算法
  • @billz std::list::erase 就够了。
【解决方案3】:

尝试添加这个:

bool compare_node_F(Node* n1, Node* n2)
{
  return n1-> F< n2-> F;
}

#include <list>
#include <algorithm>
#include <cstdlib>
#include <iostream>

int main()
{
  std::list<Node*> nodes;
  for(int i= 100; i--;)
  {
    Node* n= new Node(42, 42, 42);
    n-> F= i;
    nodes.push_back(n);
  }
  std::list<Node*>::iterator min_element_iter= std::min_element(nodes.begin(), nodes.end(), compare_node_F);
  std::cout<< "Min F: "<< (*min_element_iter)-> F<< '\n';
  for(std::list<Node*>::iterator d= nodes.begin(); d!= nodes.end(); ++ d)
    delete *d;
}

【讨论】:

    猜你喜欢
    • 2023-03-03
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 2017-06-29
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多