Избегайте цикла и выполните один INSERT INTO ... SELECT
запрос. Прямо сейчас вы повторно используете один и тот же курсор снаружи и внутри цикла, вызывая проблемы с обработкой. Либо используйте два разных курсора, либо эффективно объединяйте и выполняйте запрос действия запуска механизма базы данных:
sql = '''INSERT INTO Counts (org, [count])
SELECT SUBSTR(email, INSTR(email, '@')+1) AS org,
SUM(count) as [count]
FROM Em
GROUP BY org
ORDER BY count DESC
'''
cur.execute(sql)
conn.commit()
Это кажется невозможным в моей ситуации, поскольку упомянутая мною функция является функцией поиска
unordered_set
.
Используете ли вы пользовательские объекты хеш-функции / предиката? Если нет, то вы должны передать unordered_set
указатель на точный вектор, который вы хотите найти. Указатель на другой вектор с таким же содержимым не будет работать. Это не очень полезно для поиска, если не сказать больше.
Было бы лучше использовать unordered_set
, потому что тогда вы можете выполнять поиск по значению. Я думаю, что это также потребует пользовательского объекта хэш-функции, потому что хэш
, насколько мне известно, не имеет специализации для vector
.
В любом случае, указатель на середину вектор сам по себе не является вектором, как объяснили другие. Вы не можете конвертировать итератор в указатель на вектор без копирования его содержимого.
Я не проверял это, но не могли бы вы вместо этого использовать набор пар итераторов? Каждая пара итераторов будет представлять начальный и конечный итератор вектора последовательности. Например:
typedef std::vector<int> Seq;
typedef std::pair<Seq::const_iterator, Seq::const_iterator> SeqRange;
bool operator< (const SeqRange& lhs, const SeqRange& rhs)
{
Seq::const_iterator lhsNext = lhs.first;
Seq::const_iterator rhsNext = rhs.first;
while (lhsNext != lhs.second && rhsNext != rhs.second)
if (*lhsNext < *rhsNext)
return true;
else if (*lhsNext > *rhsNext)
return false;
return false;
}
typedef std::set<SeqRange, std::less<SeqRange> > SeqSet;
Seq sequences;
void test (const SeqSet& seqSet, const SeqRange& seq)
{
bool find = seqSet.find (seq) != seqSet.end ();
bool find2 = seqSet.find (SeqRange (seq.first + 1, seq.second)) != seqSet.end ();
}
Очевидно, что векторы должны храниться в другом месте, как и раньше. Также, если вектор последовательности изменяется, его запись в наборе должна быть удалена и повторно добавлена, поскольку итераторы могли измениться.
Джон
Прямой ответ на ваш вопрос - да. Если foo является вектором, вы можете сделать это: & foo [1].
Однако это работает только для векторов, потому что в стандарте говорится, что векторы реализуют хранилище с использованием неконтролируемой памяти.
Но вы все еще можете (и, вероятно, должны ) передайте итераторы вместо необработанных указателей, потому что это более выразительно. Проходящие итераторы не делают копию вектора.
Например, мой
vector
содержит (5,2,6,87,251). Функция принимаетfoo vector
, и я хочу передать ей указатель на (2,6,87,251).*
Указатель на vector
не является вообще то же самое, что указатель на элементы вектора.
Для этого вам нужно создать новый вектор
, содержащий только те элементы, на которые вы хотите передать указатель. Примерно так:
vector<int> tempVector( foo.begin()+1, foo.end());
// now you can pass &tempVector to your function
Однако, если ваша функция получает указатель на массив из int, вы можете передать & foo [1]
.
Ваша функция не должна принимать vector
; в зависимости от ситуации следует использовать vector
или vector
. Затем просто введите foo.begin () + 1
.
Если можешь, лучшим выбором может быть изменение функции на использование итератора для элемента или нового вектора (если он не изменяется).
Хотя вы можете делать такие вещи с массивами, так как знаете, как они хранятся Это, вероятно, плохая идея сделать то же самое с векторами. & foo [1]
не имеет тип vector
.
Кроме того, хотя реализация STL доступна онлайн, обычно рискованно пытаться полагаться на внутренний структура абстракции.
Если ваша функция действительно принимает vector
(указатель на вектор), то Вы должны передать & foo
, так как это будет указатель на вектор. Очевидно, что это не просто решит вашу проблему, но вы не сможете напрямую преобразовать итератор в вектор, так как память по адресу итератора не будет напрямую обращаться к действительному вектору.
Вы можете создать новый вектор, вызвав векторный конструктор :
template <class InputIterator> vector(InputIterator, InputIterator)
Это создает новый вектор путем копирования элементов между двумя итераторами. Вы бы использовали это примерно так:
bar(std::vector<int>(foo.begin()+1, foo.end());
Вектор - это контейнер с полным владением своими элементами. Один вектор не может содержать частичное представление другого, даже const-представление. Это коренная причина здесь.
Если вам это нужно, создайте свой собственный контейнер, который имеет представления со слабым_пломером к данным, или посмотрите на диапазоны. Пара итераторов (даже указатели работают как итераторы в векторе) или, что еще лучше, boost :: iterator_range, которые работают довольно легко.
Это зависит от шаблонности вашего кода. Используйте std :: pair, если вам нужно скрыть код в cpp.
Здесь оно есть, получение ссылки на соответствующее указатель итератора Использование:
Пример:
string my_str= "hello world";
string::iterator it(my_str.begin());
char* pointer_inside_buffer=&(*it); //<--
[Оператор уведомления * возвращает ссылку , чтобы делать и на ссылке даст вам адрес].