Qt - 棘手的搜索算法 - 列表中的重复或“镜像”重复

时间:2013-07-29 15:06:29

标签: qt list search duplicate-removal

想象一下:我有一个JSON文件,其中包含Node个对象列表,其中包含Link类型的列表。类似的东西:

node1:
    links: node1,node2
           node3,node1
           node1,node6

node2:
    links: node2,node1
           node2,node9
           node7,node2

我需要识别唯一的链接对 - 即(node_a,node_b)对。请注意,(node_b,node_a)代表相同的内容

Link类具有getter方法,返回指向源/目标Node的指针。在该文件中,有关链接的信息存储为具有source节点名称和destination节点名称的字符串,如:(source,destination)

当我从文件构建我的结构时,我首先创建Nodes然后才创建LinksLink构造函数如下:

Link::Link(Node *fromNode, Node *toNode)

我的代码创建链接:

        QList<Link*> consumedLinks; // list where I was trying to place all the non-duplicate links

        // for each node in the file
        foreach(QVariant nodesMap, allNodesList){
            QVariantMap node1 = nodesMap.toMap();
            QList<QVariant> nodeDetails = node1["node"].toList();
            QVariantMap allLinksMap = nodeDetails.at(9).toMap();

            // extract all the links of the node to a list of QVariant
            QList<QVariant> linksList = allLinksMap["links"].toList();

            // for each Link in that list
            foreach(QVariant linkMap, linksList){
                QVariantMap details = linkMap.toMap();
                Node *savedFromNode;
                Node *savedToNode;

                // get all the Items in the scene
                QList<QGraphicsItem*> itemList = scene->items();

                // cast each item to a Node
                foreach(QGraphicsItem *item, itemList){
                    Node* tempNode = qgraphicsitem_cast<Node*>(item);
                    if(tempNode){
                        // check what the node name matches in the link list
                        if(tempNode->text()==details["fromNode"]){
                            savedFromNode = tempNode;
                        }
                        if(tempNode->text()==details["toNode"]){
                            savedToNode = tempNode;
                        }
                    }
                }

                // create the link
                Link *linkToCheck = new Link(savedFromNode,savedToNode);

                // add it to the links list (even if duplicate)
                consumedLinks.append(linkToCheck);
            }
        }

        // add all the links as graphics items in the scene
        foreach(Link *linkToCheck, consumedLinks){
            scene->addItem(linkToCheck);
        }

所以现在这不会检查consumedLinks列表中的重复项(显然)。关于如何实现这一点的任何想法?

注意:我知道上面的伪JSON无效,只是为了让您了解结构。

注意2:我重新说明并在问题中添加了详细信息和代码,以便更清楚地了解我需要的内容。

2 个答案:

答案 0 :(得分:1)

1.规范化链接,即(a, b)时将(b, a)替换为b < a。每个链接都应表示为(a, b)a < b

2.创建一个QSet< QPair<Node*, Node *> >变量并将所有链接放入其中。可以使用qMakePair(node1, node2)制作每个链接对象。由于QSet是一个qnique容器,因此将自动删除所有重复项。

答案 1 :(得分:0)

好吧,我并没有像@Riateche所建议的那样做,但类似的东西。

我基本上创建了一个QList<QPair<QString,QString> >,因此我可以轻松检查重复项,然后根据Link列表中的项目创建了QPair列表。类似的东西:

        QList<Node*> existingNodes;
        QList<QPair<QString,QString> > linkPairList;
        QList<QGraphicsItem*> itemList = scene->items();

        foreach(QGraphicsItem *item, itemList){
            Node* tempNode = qgraphicsitem_cast<Node*>(item);
            if(tempNode){
                existingNodes.append(tempNode);
            }
        }

        foreach(QVariant nodesMap, allNodesList){
            QVariantMap node1 = nodesMap.toMap();
            QList<QVariant> nodeDetails = node1["node"].toList();
            QVariantMap allLinksMap = nodeDetails.at(9).toMap();


            QList<QVariant> linksList = allLinksMap["links"].toList();
            foreach(QVariant linkMap, linksList){
                QVariantMap details = linkMap.toMap();

                QPair<QString,QString>linkPair(details["fromNode"].toString(),details["toNode"].toString());
                QPair<QString,QString>reversedLinkPair(details["toNode"].toString(),details["fromNode"].toString());

                if(!linkPairList.contains(linkPair)){
                    // !dupe
                    if(!linkPairList.contains(reversedLinkPair)){
                        // !reversed dupe
                        linkPairList.append(linkPair);
                    }
                }
                qDebug()<<"number of pairs: "<<linkPairList.size();
            }

        }
        QPair<QString,QString> linkPairInList;
        foreach(linkPairInList, linkPairList){
            Node *savedFromNode;
            Node *savedToNode;
            foreach(Node* node, existingNodes){
                if(node->text()==linkPairInList.first){
                    savedFromNode=node;
                }
                if(node->text()==linkPairInList.second){
                    savedToNode=node;
                }
            }
            Link *newLink = new Link(savedFromNode,savedToNode, "input");
            scene->addItem(newLink);
        }

这是正确的答案,因为它解决了我需要解决的问题。因为我只是因为@ Riateche的评论而到达那里,所以我给他的答案+1了。