2016-05-25 2 views
0

У меня есть вопрос об изменении или замене элементов в списке. У меня есть класс:Как изменить значение элемента в списке stl?

class Node{ 
public: 
    elType type; // enum 
    string name; 

    Node(elType type, string name); 
    ~Node(); 

    void printNodeInfo(); 
} 

и список:

std::list <Node * > someList; 

Теперь, как я могу заменить значение (для eaxmple типа изменения) в таком элементе. Я попытался это:

 std::list<Node * >::iterator it = someList.end(); 
     it--; 

     while(openName.compare((*it)->name) != 0) 
      it--; 

     (*it)->type = otherType; 

Но это не похоже на работу, вид остается неизменным. Я был бы благодарен за любую помощь.


EDIT: Я обновил список, так что теперь у меня есть:

std::list <Node> someList; 

и изменил замена на:

it->type = otherType; 

Я также попытался:

std::list<Node >::iterator it2 = someList.erase(it); 
Node temp(otherType, openName); 
someList.insert(it2, temp); 

после этого для бота h - простой способ печати:

it2->printNodeInfo(); 

ничего не выводит.

+1

Ваш поиск воссоздавая 'std :: find_if', и вы также можете использовать равное равенство:' str == otherStr' – chris

+0

ваш цикл while должен проверяться с помощью begin(), чтобы он не продолжался за пределами, если он не нашел 'name' –

+0

Убедитесь, что * это не nullptr. Тип печати после настройки. Используйте отладчик. –

ответ

0

Интересно, почему вы используете Node * вместо Node. Рассмотрите возможность использования list<Node> вместо list<Node *>, если вы не можете дать причину, почему нет.

Предполагаю, что list<Node>.

Чтобы найти элемент, используйте find из STL. Вы можете использовать его так: find(someList.begin(), someList.end(), value); значение будет иметь тип elType в вашем случае.

Вы также должны предоставить оператор сравнения, который сравнивает имя узла с именем имени.

Не имея достаточной информации, я сделал упрощенный пример. Возможно, это поможет вам скорректировать/приблизиться к тому, чего вы хотите достичь.

// Example program 
#include <iostream> 
#include <string> 
#include <list> 
#include <algorithm> 

enum elType { red, green, blue }; 

using namespace std; 

class Node{ 
public: 
    elType type; // enum 
    string name; 

    Node(elType type, string name); 
}; 

Node::Node(elType type, string name) { 
    this->type = type; 
    this->name = name; 
}; 

// ensure that name can be found using find of STL 
bool operator==(Node &n, string name) { 
    return n.name == name; 
} 

int main() { 

    // Create nodes 
    Node n1(elType::red, "Node 1"); 
    Node n2(elType::green, "Node 2"); 
    Node n3(elType::blue, "Node 3"); 

    // Output node names and types 
    cout << n1.name << " : " << n1.type << endl; 
    cout << n2.name << " : " << n2.type << endl; 
    cout << n3.name << " : " << n3.type << endl; 

    // Create list of nodes 
    list<Node> someList{ n1, n2, n3 }; 

    // find node with name "Node 3" 
    auto it = find(someList.begin(), someList.end(), "Node 3"); 

    // if a node was found change its type to red 
    if (it != someList.end()) { 
     it->type = elType::red; 
    } 

    // output nodes in list 
    cout << endl; 
    for (auto node: someList) { 
     cout << node.name << " : " << node.type << endl; 
    } 

    return 0; 
} 

Вы можете, как упомянули другие пользователи, также использовать обратный итератор.
В этом случае простой замены begin() и end() по rbegin() и rend() так:

// find node with type "blue" and change type to "red" 
    auto it = find(someList.begin(), someList.end(), "Node 3"); 

    // if a node was found change its type 
    if (it != someList.end()) { 
     it->type = elType::red; 
    } 
+0

Хорошо, я изменил список на список , но кажется, что я все еще не могу заменить значения в объекте. – michszm

+0

Обновите свой вопрос своими изменениями. Вы должны показать, что вы пробовали. – Elyasin

+1

OP пытается выполнить поиск по 'name' not' type', поэтому ваш 'operator ==()' должен быть соответствующим образом скорректирован. – Robin

1

Я не знаю, что это ваша проблема точно, но вот ваше решение:

#include <iostream> 
#include <string> 
#include <list> 

using namespace std; 

class Node{ 
public: 
    int type; // enum 
    string name; 

    Node(int type, string name) : type(type), name(name) {} 
    ~Node(){} 

    void printNodeInfo() const {cout << type << ", " << name << endl;} 
}; 

void replace(list<Node> &l, const string &nameSearch, int typeReplace) { 
    for (auto it = l.rbegin(); it != l.rend(); it++) { 
     if (it->name == nameSearch) { 
      it->type = typeReplace; 

      /* To stop searching */ 
      return; 
     } 
    } 
    /* Nothing replaced, error message? */ 
} 

int main() { 
    list<Node> l; 

    l.push_back(Node(0, "World")); 
    l.push_back(Node(1,"Hello")); 
    l.push_back(Node(2,"World")); 

    replace(l, "World", 42); 

    for (const auto &el: l) { 
     el.printNodeInfo(); 
    } 

    return 0; 
} 
+0

Как я вижу, вы заменили бы первый узел на тип «2» и установили 'type = 42;'. OP хочет найти последнее совпадающее 'name' и установить' type', поэтому это не совсем решение. – Robin

+0

Спасибо за уловку, код обновлен. – coyotte508

+0

Не совсем. Теперь вы выполняете поиск по типу и заменяете 'name' - OP хотите противоположное. ;-) Кроме того, вы по-прежнему найдете первый матч, а не последний. См. Комментарии ФП к вопросу выше. – Robin

Смежные вопросы