c++ - 我如何在我的程序中使用这个单链表结构来提高我的性能?

标签 c++ performance linked-list

大家好,我有一个程序可以对字符串集进行操作。我要实现两组字符串的加减等功能。我需要将其降低到 O(N+M) 的性能,其中 N、M 是字符串集。现在,我相信我的表现是 O(N*M),因为我对 N 的每个元素,我都遍历了 M 的每个元素。我特别专注于获得正确性能的减法,好像我可以将其归结为适当的性能,我相信我可以将这些知识运用到我必须实现的其他事情中。

例如,'-' 运算符假设是这样工作的。

声明set1为空集。
声明 set2 为包含 { a b c } 元素的集合
声明 set3 是一个包含 ( b c d } 元素的集合

组 1 = 组 2 - 组 3

现在 set1 假设等于 { a }。所以基本上,只需从 set3 中删除也在 set2 中的任何元素。

对于加法实现(重载“+”运算符),我还对字符串进行排序(因为我们必须这样做)。

顺便说一句,所有功能现在都可以正常工作。

所以我想知道是否有人可以

a) 确认目前我正在做 O(N*M) 性能
b) 给我一些关于如何将性能提高到 O(N+M) 的想法/实现

注意:我不能向类 strSet 或节点结构添加任何成员变量或函数。

主程序的实现不是很重要,但我会贴出我的类定义和成员函数实现的代码:

strSet2.h(我的类和结构的实现)

// Class to implement sets of strings

// Implements operators for union, intersection, subtraction,
//  etc. for sets of strings

// V1.1 15 Feb 2011 Added guard (#ifndef), deleted using namespace RCH

#ifndef _STRSET_
#define _STRSET_

#include <iostream>
#include <vector>
#include <string>
// Deleted: using namespace std;  15 Feb 2011 RCH

struct node {
    std::string s1;
    node * next;
};

class strSet {

private:
    node * first;

public:
    strSet ();  // Create empty set
    strSet (std::string s); // Create singleton set
    strSet (const strSet &copy); // Copy constructor
    ~strSet (); // Destructor

    int SIZE() const;

    bool isMember (std::string s) const;

    strSet  operator +  (const strSet& rtSide);  // Union
    strSet  operator -  (const strSet& rtSide);  // Set subtraction
    strSet& operator =  (const strSet& rtSide);  // Assignment


};  // End of strSet class

#endif  // _STRSET_

strSet2.cpp(成员函数的实现)

#include <iostream>
#include <vector>
#include <string>
#include "strset2.h"

using namespace std;

strSet::strSet() {
    first = NULL;
}

strSet::strSet(string s) {
    node *temp;
    temp = new node;
    temp->s1 = s;
    temp->next = NULL;
    first = temp;
}

strSet::strSet(const strSet& copy) {
    if(copy.first == NULL) {
        first = NULL;
    }
    else {
        node *n = copy.first;
        node *prev = NULL;
        while (n) {
            node *newNode = new node;
            newNode->s1 = n->s1;
            newNode->next = NULL;
            if (prev) {
                prev->next = newNode;
            }
            else {
                first = newNode;
            }
            prev = newNode;
            n = n->next;
        }
    }
}

strSet::~strSet() {
    if(first != NULL) {
        while(first->next != NULL) {
            node *nextNode = first->next;
            first->next = nextNode->next;
            delete nextNode;
        }
    }
}

int strSet::SIZE() const {
    int size = 0;
    node *temp = first;
    while(temp!=NULL) {
        size++;
        temp=temp->next;
    }
    return size;
}    

bool strSet::isMember(string s) const {
    node *temp = first;
    while(temp != NULL) {
        if(temp->s1 == s) {
            return true;
        }
        temp = temp->next;
    }
    return false;
}

strSet strSet::operator +  (const strSet& rtSide) {
    strSet newSet;
    newSet = *this;
    node *temp = rtSide.first;
    while(temp != NULL) {
        string newEle = temp->s1;
        if(!isMember(newEle)) {
            if(newSet.first==NULL) {
                node *newNode;
                newNode = new node;
                newNode->s1 = newEle;
                newNode->next = NULL;
                newSet.first = newNode;
            }
            else if(newSet.SIZE() == 1) {
                if(newEle < newSet.first->s1) {
                    node *tempNext = newSet.first;
                    node *newNode;
                    newNode = new node;
                    newNode->s1 = newEle;
                    newNode->next = tempNext;
                    newSet.first = newNode;
                }
                else {
                    node *newNode;
                    newNode = new node;
                    newNode->s1 = newEle;
                    newNode->next = NULL;
                    newSet.first->next = newNode;
                }
            }
            else {
                node *prev = NULL;
                node *curr = newSet.first;
                while(curr != NULL) {
                    if(newEle < curr->s1) {
                        if(prev == NULL) {
                            node *newNode;
                            newNode = new node;
                            newNode->s1 = newEle;
                            newNode->next = curr;
                            newSet.first = newNode;
                            break;
                        }
                        else {
                            node *newNode;
                            newNode = new node;
                            newNode->s1 = newEle;
                            newNode->next = curr;
                            prev->next = newNode;
                            break;
                        }
                    }
                    if(curr->next == NULL) {
                        node *newNode;
                        newNode = new node;
                        newNode->s1 = newEle;
                        newNode->next = NULL;
                        curr->next = newNode;
                        break;
                    }
                    prev = curr;
                    curr = curr->next;
                }
            }
        }
        temp = temp->next;
    }
    return newSet;
}

strSet strSet::operator - (const strSet& rtSide) {
    strSet newSet;
    newSet = *this;
    node *temp = rtSide.first;
    while(temp != NULL) {
        string element = temp->s1;
        node *prev = NULL;
        node *curr = newSet.first;
        while(curr != NULL) {
            if( element < curr->s1 ) break;
            if( curr->s1 == element ) {
                if( prev == NULL) {
                    node *duplicate = curr;
                    newSet.first = newSet.first->next;
                    delete duplicate;
                    break;
                }
                else {
                    node *duplicate = curr;
                    prev->next = curr->next;
                    delete duplicate;
                    break;
                }
            }
            prev = curr;
            curr = curr->next;
        }
        temp = temp->next;
    }
    return newSet;
}

strSet& strSet::operator =  (const strSet& rtSide) {
    if(this != &rtSide) {
        if(first != NULL) {
            while(first->next != NULL) {
                node *nextNode = first->next;
                first->next = nextNode->next;
                delete nextNode;
            }
        }
        if(rtSide.first == NULL) {
            first = NULL;
        }
        else {
            node *n = rtSide.first;
            node *prev = NULL;
            while (n) {
                node *newNode = new node;
                newNode->s1 = n->s1;
                newNode->next = NULL;
                if (prev) {
                    prev->next = newNode;
                }
                else {
                    first = newNode;
                }
                prev = newNode;
                n = n->next;
            }
        }
    }
    return *this;
}

最佳答案

是的,我相信您当前的 operator- 是 O(N*M)。

因为这是作业,我不想给你太多信息,但是......

如果你的链表是有序的,那么你可以在 O(N+M) 中写减法。这给你留下了两个问题:如何保持列表有序?以及如何在给定有序列表的情况下编写 O(N+M) 减法算法。

关于c++ - 我如何在我的程序中使用这个单链表结构来提高我的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5333252/

相关文章:

union 访问成本与使用基本类型

ruby - Ruby 进程如何限制其 CPU 使用率?

c - 为什么我们使用指向指针的指针

c++ - 这是启动和停止线程的安全方法吗?

c++ - 没有重载运算符的转换运算符

c++ - Ramer-Douglas-Peucker 路径简化算法

mysql - 查询MySQL中的大表

c - 链表从小到大排序

Java循环链表

c++ - 处理具有不同类型参数的 std::basic_string<>