C++ 写这个算法更有效吗?
目前正在从事图书馆模拟器任务。一切都很好,但我想知道一些只是为了了解它 在这个项目中有三个类:书籍、赞助人和图书馆。library类包含3个私有数据成员:指向书籍的指针向量、指向用户指针的向量和currentDate int 有关职能如下: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*>
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
for
循环语法非常不透明,可能有很多错误。C++11为循环语法引入了一个更干净的,可以在标准库容器(如map
或vector
)中进行迭代。使用:for(auto-it:vector\u-name)
。如果您需要修改每一个,请使用it
——迭代器的引用限定符
使用增量前语法尽可能降低加速比
++i
和i++
略有不同++i
在继续计算对象之前,直接修改它在表达式中出现的位置<代码>i++
创建对象的副本,返回它,并增加原始值。创建一个值或对象的副本在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);
}
}