Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 写这个算法更有效吗?_C++_Performance_Function - Fatal编程技术网

C++ 写这个算法更有效吗?

C++ 写这个算法更有效吗?,c++,performance,function,C++,Performance,Function,目前正在从事图书馆模拟器任务。一切都很好,但我想知道一些只是为了了解它 在这个项目中有三个类:书籍、赞助人和图书馆。library类包含3个私有数据成员:指向书籍的指针向量、指向用户指针的向量和currentDate int 有关职能如下: void Library::incrementCurrentDate() { currentDate++; for (int i = 0; i < members.size(); i++) { vector<Book*>

目前正在从事图书馆模拟器任务。一切都很好,但我想知道一些只是为了了解它

在这个项目中有三个类:书籍、赞助人和图书馆。library类包含3个私有数据成员:指向书籍的指针向量、指向用户指针的向量和currentDate int

有关职能如下:

void Library::incrementCurrentDate()
{
  currentDate++;

  for (int i = 0; i < members.size(); i++)
  {
    vector<Book*> ptr = members.at(i)->getCheckedOutBooks();

     for (int j = 0; j < ptr.size(); j++)
      {
        if (currentDate > ptr.at(j)->getCheckOutLength())
            members.at(i)->amendFine(.10);
      }
  }
} 
void库::incrementCurrentDate()
{
currentDate++;
对于(int i=0;igetCheckedOutBooks();
对于(int j=0;jptr.at(j)->getCheckOutLength())
(i)->amendFine(.10);
}
}
} 
该功能的要求如下:

增加当前日期;每一位顾客借出一本过期的书,就要增加10美分的罚款(使用amendFine)


我上面写的方式现在很好用。由于我刚刚进入计算机科学课程的第一学期,我们不能使用我们没有涵盖的任何东西,我知道这是很多。有了这个说法,有没有更有效的方法来使用更高级的C++编程方法实现这个功能?

自从我使用C++以来,已经有一段时间了,但是几乎总是标准库比你自己的实现快。为了便于参考,请查看与相关的标准功能(此网站非常有用)

您可以通过其他一些过滤逻辑来精简
ptr.size()
,这样您就不必迭代那些没有过期书籍的人(可能需要对书籍及其到期日期进行排序?)

  • 如果大小不是非常大,请使用
    std::vector
  • 指针总是有一个与之相关的代价,因为它涉及间接性。查找地址并在内存中访问地址可能无法由编译器优化,因此将涉及访问内存的成本。内存访问通常是系统性能的瓶颈,因此最好尝试将内存中的内容彼此靠近,并尝试构建程序,以便访问内存最少

  • 如果数据非常大,请使用数据库系统,如SQL
  • 另一方面,我们可以放弃所有肮脏的工作,使用一个已建立的数据库库或程序。像MySQL这样的东西可以很容易地管理大量数据,同时还可以使用一种很棒的编程语言来访问和管理数据。某些数据库,如PostgreSQL,可以扩展到大型数据集。熟悉它也会很有帮助。例如,甚至一些移动应用程序也可能使用Android的MySQL

  • 对于循环迭代语法,请使用现代C++11或更高版本的
  • 当前的
    for
    循环语法非常不透明,可能有很多错误。C++11为
    循环语法引入了一个更干净的
    ,可以在标准库容器(如
    map
    vector
    )中进行迭代。使用:
    for(auto-it:vector\u-name)
    。如果您需要修改每一个,请使用
    it
    ——迭代器的引用限定符

  • 使用增量前语法尽可能降低加速比
  • ++i
    i++
    略有不同
    ++i
    在继续计算对象之前,直接修改它在表达式中出现的位置<代码>i++
    创建对象的副本,返回它,并增加原始值。创建一个值或对象的副本在C++中是有代价的,因此避免在某些情况下是有用的,无论如何,这是一个很好的约定。
  • 通过
    常数&
    。不仅仅是常规的参考
  • <>函数参数在C++中默认值传递。这意味着C++只复制对象的副本。然而,当有突变重复应用于对象时,比如说,使用函数随时间改变整数的值,您可能希望通过引用传递。引用基本上传递“真实”对象,这意味着对引用所做的任何更改都是在“真实”对象上完成的

    现在,为什么要传递不可修改的对象?因为它可以带来更好的优化。通过常量引用传递,编译器可以对代码做出更有力的假设(例如,由于引用不能在程序过程中更改,因此在函数中多次引用同一引用不需要重新加载参数的值,因为它在函数中不应更改)

  • 使用
    std::unique\u ptr
    std::shared\u ptr

  • 智能指针也是C++11引入的一个很好的功能,它包括通过将其生存期附加到作用域来自动释放自己的指针。换句话说,不需要使用
    new
    delete
    ——只需创建指针,您不必跟踪何时释放内存。这可以得到在某些情况下比较复杂,但一般来说,使用智能指针会带来更好的安全性和更少的内存管理问题的变化,这就是为什么它们首先被引入标准库的原因。

    我想这里有几个问题需要回答。第一个问题是:这种算法能更有效吗另一个问题:我在C++中实现算法是否更有效?< /P> 对于第一个问题,我的答案是否定的。基于这个问题,我觉得你没有比O(n^2)更好的信息

    如评论中所述,您可以迭代每个人并按到期日期对其书籍进行排序。实际上,这可以节省一些时间,但理论上书籍查找仍然是线性时间O(n)。此外,您还需要增加排序的开销,使算法现在为O(mnlog(n)),其中m是
    currentDate++;
    vector<Book*> ptr = members.at(i)->getCheckedOutBooks();
    for(....)
    
    member -> list(checked out books)
    book -> check-out length // presumably the due date for returning the book
    
    check-out length -> list(checked out books with that due date)
    book -> member who checked it out
    
    int checkedDateComparator(Patron & leftHand, Patron & rightHand){
        return leftHand.getCheckedOutLength() < rightHand.getCheckOutLength();  
    }
    bool operator==(Patron & a, Patron & b){
        return a.getCheckedOutLength() < b.getCheckOutLength();
    }
    void Library::incrementCurrentDate()
    {
        currentDate++;
    
        for (int i = 0; i < members.size(); i++)
        {
            vector<Book*> ptr = members.at(i)->getCheckedOutBooks();
            Book dummy; //dummy used for find the fines 
            dummy.setCheckedOutLength(currentDate);
            int overdue = ptr.end() - upper_bound(ptr.begin(), ptr.end(), dummmy, checkedDateComparator);
            members.at(i)->amendFine(overdue* .01);
       }
    } 
    
    float CalculateFees(Patron patron)
    {
        float result = 0;
        foreach(checkedOutBook in patron.GetCheckedOutBooks())
        {
            result += CalculateFee(checkedOutBook.CheckOutDate(), today);
        }
        return result;
    }
    
    float CalculateFee(Date checkOutDate, Date today)
    {
        return (today.Day() - checkOutDate.Day()) * 0.10;
    }
    
    void AttemptCheckout(Patron patron, BookList books)
    {
        float fees = CalculateFees(patron);
        if(fees == 0 || (fees > 0 && PatronPaysFees(patron, fees)))
        {
            Checkout(patron, books);
        }
        else
        {
            RejectCheckout(patron);
        }
    }