В настоящее время я работаю над классом базы данных ДНК, и в настоящее время я связываю каждую строку в базе данных как с оценкой совпадения (на основе расстояния редактирования), так и с фактической последовательностью ДНК, безопасно ли сначала изменить таким образом в цикле итерации?
typedef std::pair<int, DnaDatabaseRow> DnaPairT;
typedef std::vector<DnaPairT> DnaDatabaseT;
// ....
for(DnaDatabaseT::iterator it = database.begin();
it != database.end(); it++)
{
int score = it->second.query(query);
it->first = score;
}
Причина, по которой я делаю это, состоит в том, что позже я могу отсортировать их по баллам. Я пробовал карты и получил ошибку компиляции о внесении изменений в первую очередь, но есть ли лучший способ сохранить всю информацию для последующей сортировки?





Чтобы ответить на ваш первый вопрос, да. Изменять элементы вашей пары совершенно безопасно, поскольку фактические данные в паре не влияют на сам вектор.
редактировать: У меня такое ощущение, что вы получали ошибку при использовании карты, потому что вы пытались изменить значение first внутренней пары карты. Это было бы недопустимо, потому что это значение является частью внутренней работы карты.
Как заявил дрибес:
In maps you cannot change first as it would break the invariant of the map being a sorted balanced tree
редактировать: Чтобы ответить на ваш второй вопрос, я не вижу ничего плохого в том, как вы структурируете данные, но я бы хотел, чтобы база данных содержала указатели для объектов DnaPairT, а не самих объектов. Это резко уменьшит объем памяти, который копируется во время процедуры сортировки.
#include <vector>
#include <utility>
#include <algorithm>
typedef std::pair<int, DnaDatabaseRow> DnaPairT;
typedef std::vector<DnaPairT *> DnaDatabaseT;
// ...
// your scoring code, modified to use pointers
void calculateScoresForQuery(DnaDatabaseT& database, queryT& query)
{
for(DnaDatabaseT::iterator it = database.begin(); it != database.end(); it++)
{
int score = (*it)->second.query(query);
(*it)->first = score;
}
}
// custom sorting function to handle DnaPairT pointers
bool sortByScore(DnaPairT * A, DnaPairT * B) { return (A->first < B->first); }
// function to sort the database
void sortDatabaseByScore(DnaDatabaseT& database)
{
sort(database.begin(), database.end(), sortByScore);
}
// main
int main()
{
DnaDatabaseT database;
// code to load the database with DnaPairT pointers ...
calculateScoresForQuery(database, query);
sortDatabaseByScore(database);
// code that uses the sorted database ...
}Единственная причина, по которой вам может потребоваться более эффективные методы, заключается в том, что ваша база данных настолько огромна, что цикл сортировки занимает слишком много времени. Однако, если это так, я бы предположил, что ваша функция query будет занимать большую часть времени обработки.
@dribeas: Идеальное описание. благодарю вас! Я добавил эту строчку к своему ответу.
Вы не можете изменить, так как переменная первая в std :: pair определена как const
В картах вы не можете сначала изменить, так как это нарушит инвариант карты, являющейся отсортированным сбалансированным деревом.