什么是关联容器?必须更改此容器的QList

What is an associative container? Have to change QList given to this container

本文关键字:QList 关联 什么      更新时间:2023-10-16

我有一个作业,我真的不知道该做什么。我必须重写一个应用程序(它在上一个作业中,我们得到了答案),以便SavingsAccount的m_TransactionList是一个合适的关联容器,而不是QList。我将给出代码中使用m_TransactionList的部分。如果我发布所有内容,那就需要大量代码。。我们有以下.h和.cpp文件:存款、取款、余额查询、交易和储蓄账户。

这是savingsaccount.h

#ifndef SAVINGSACCOUNT_H
#define SAVINGSACCOUNT_H
#include "transaction.h"
class SavingsAccount{
public:
SavingsAccount(QString name, QString num);
~SavingsAccount();
void addTransaction(Transaction* t);
double totalTransactionCost()const;
QString frequentTransactionType() const;
QList<Transaction*> transactionsOnADate(QDate date) const;
QString toString() const;
private:
QString m_CustomerName;
QString m_AccountNumber;
QList<Transaction*> m_TransactionList;
};
#endif // SAVINGSACCOUNT_H

savingsaccount.cpp

#include <QStringList>
#include "savingsaccount.h"
SavingsAccount::SavingsAccount(QString name, QString num): m_CustomerName(name), m_AccountNumber(num){
}
SavingsAccount::~SavingsAccount(){
qDeleteAll(m_TransactionList);
}
void SavingsAccount::addTransaction(Transaction *t){
m_TransactionList.append(t);
}
double SavingsAccount::totalTransactionCost()const{
double cost = 0.0;
foreach(Transaction* t, m_TransactionList){
cost +=t->computeCost();
}
return cost;
}
QString SavingsAccount::frequentTransactionType() const{
int dCount = 0, wCount = 0, beCount =0, mostCount = 0;
QString dTransaction = "Deposit", wTransaction = "Withdrawal", beTransaction = "Balance Enquiry";
QStringList result;
foreach(Transaction* t, m_TransactionList){
QString type = t->getType();       
if (type == dTransaction)
dCount++;
if (type ==  wTransaction)
wCount++;
if (type == beTransaction)
beCount++;
}
mostCount = dCount > wCount ? dCount : wCount;
mostCount = beCount > mostCount ? beCount : mostCount;
if (mostCount == dCount)
result.append(dTransaction);
if (mostCount == wCount)
result.append(wTransaction);
if (mostCount == beCount)
result.append(beTransaction);
return result.join(", ");
}
QList<Transaction *> SavingsAccount::transactionsOnADate(QDate date) const{
QList<Transaction*> result;
foreach(Transaction* t, m_TransactionList){
if (t->getDateTime().date() == date)
result.append(t);
}
return result;
}
QString SavingsAccount::toString() const{
QString result = QString("Customer name: %1, Account number: %2n").arg(m_CustomerName).arg(m_AccountNumber);
foreach(Transaction* t, m_TransactionList){
result.append(t->toString());
result.append("n");
}
return result;
}

我不知道该做什么,该改变什么!

Qt有许多关联容器:

QMap      - a generic map/dictionary, implemented as a R/B tree since Qt5
QMultimap - same as QMap, but has API for multiple values per key
QHash     - a generic hashmap, can be significantly faster than QMap as element count increases
QMutihash - like QHash, but has API for multiple values per key

为了使您的类型能够使用这些运算符,QMapQMultimap需要<运算符,而QHashQMultihash需要==运算符和免费的uint qHash(T)函数。

如果您使用指针,这些要求将不适用,因为它们已经实现了这些要求。

然而,为了使用关联容器,你需要为每个值都有一个键,就交易而言,这可能是一个整数ID。这就引出了我的观点——如果交易ID是每个储蓄账户的,它们将是连续的,换句话说,你会更好地使用QList,甚至QVector,因为它会更高效,因为您将只追加事务。

此外,有些人可能会认为QListQVector也可以被视为关联容器,因为索引可以有效地被视为键。主要的区别在于元素是如何存储的,它们在内存中是否是顺序的,以及它们是有序的还是无序的,每一个元素都有自己的优点和缺点,并满足特定的使用要求。

如果你想留在Qt世界,你可以将QList<T>更改为QMap<K,T>,其中K将是你的密钥,T是你的值。这还需要定义密钥的类型(可能是QStringint),并将迭代更改为使用QMapIterator<K,T>。这实际上是一项非常简单的工作,但它非常有助于理解容器中的差异。

//Define
QMap<QString,Transaction> transactionList;
//Insert
transactionList.insert("first", new Transaction(...)); // Transaction 1
transactionList.insert("second", new Transaction(...)); // Transaction 2
//Use
Transaction* t = transactionList.value("first"); // Will return Transaction 1