Мой вопрос отличается, потому что я не ищу range-3v решения. Кроме того, я специально спрашивал, как решить проблему со вторым циклом for. Я уже принял ответ ниже моего вопроса. Поскольку мне не нужен второй цикл for, они показали мне, как использовать один индекс, добавляя к нему 1 для нечетных итераций. Это решило мою проблему!
Я пишу функцию, которая будет принимать вектор, предполагая, что он имеет четную длину элементов; В моей функции я создаю два временных вектора из исходного вектора, где их элементами являются {0,2,4,6,...} и {1,3,5,7,...} соответственно. Затем я добавляю соответствующие индексированные элементы и сохраняю результаты в свой вектор результатов.
Вот моя функция:
void sumElementPairsFromVector(const std::vector<int>& values, std::vector<int>& result)
{
using It = std::vector<int>::const_iterator;
std::vector<int> temp1, temp2;
// First lets divide the original vector into two temp vectors
for (It it1 = values.cbegin(); it1 != values.cend(); it1 += 2)
temp1.push_back(*it1);
for (It it2 = values.cbegin() + 1; it2 != values.cend() ; it2 += 2)
temp2.push_back(*it2);
// Add each corresponding vector and store that into our results.
for (std::size_t i = 0; i < values.size() / 2; i++)
result[i] = temp1[i] + temp2[i];
}
Вот как я его использую:
int main()
{
std::vector<int> values{ 1,2,3,4,5,6 };
for (auto i : values)
std::cout << i << " ";
std::cout << '\n';
std::vector<int> results;
sumElementPairsFromVector(values, results);
for (auto i : results)
std::cout << i << " ";
std::cout << '\n';
return 0;
}
Ожидаемый результат должен быть:
1 2 3 4 5 6
3 7 11
Утверждение отладки не выполняется в этой строке кода из функции:
for (It it2 = values.cbegin() + 1; it2 != values.cend(); it2 += 2 )
Я знаю, что вызывает ошибку; на последней итерации после того, как он увеличивается на 2 и проверяет, проходит ли it2 != values.cend() конец вектора. Как это исправить?
@ИгорьР. Ну, я пытаюсь оставаться в рамках текущего стандарта банкомата. Как только я заставлю эту функцию работать правильно, я планирую превратить ее в шаблонную лямбда-функцию. я не использую буст; только стл. Я использую С++ 17 атм. нет доступа к c++20. Я также использую Visual Studio 2017 CE
Возможный дубликат Перебор нечетных (четных) элементов только в цикле на основе диапазона
@ИгорьР. Что-то вроде дубликата, но мой вопрос конкретно о том, как исправить второй цикл for в моей функции.
Этот вопрос также не имеет решения range-3v.
@ИгорьР. Хорошо, вы, кажется, правы, только один из ответов (непринятый использовал range-3v для своего ответа; и мне не особенно понравились полученные ответы. Однако мой вопрос все еще был специфичен для условий цикла for , Пользователь JeJo дал отличный ответ, на мой взгляд.





I know what is causing the error; on the last iteration after it increments by
2and goes to check ifit2 != values.cend()it is going past the end of the vector. How do I fix this?
Вам не нужны два разных цикла для перебора вектора values.
std::vector<int> temp1, temp2;
temp1.reserve(values.size() / 2); // reserve the memory
temp2.reserve(values.size() / 2);
for (std::size_t index = 0; index < values.size(); ++index)
{
if (index & 1) temp2.emplace_back(values[index]); // odd index
else temp1.emplace_back(values[index]); // even index
}
Во-вторых, results в то время не выделял никакой памяти.
result[i] = temp1[i] + temp2[i];
следовательно, за пределами неопределенного поведения. Вам следует
for (std::size_t i = 0; i < std::min(temp1.size(), temp2.size()); i++)
result.emplace_back(temp1[i] + temp2[i]);
С другой стороны, если цель состоит в том, чтобы получить результирующий вектор из сумма последовательной пары элементов, temp1 и temp2 избыточны. result можно заполнить просто:
void sumElementPairsFromVector(const std::vector<int>& values, std::vector<int>& result)
{
result.reserve(values.size() / 2);
for (std::size_t index = 0; index < values.size() - 1; index += 2)
result.emplace_back(values[index] + values[index+1]);
}
Я могу зарезервировать размер в main, прежде чем передать его функции; Не ошибка.
Тебе нужно сделать больше, чем reserve, @Francis. На самом деле вам нужно создать элементы, прежде чем назначать их.
Я пробовал это; но вывод не правильный. Я получаю 3 3 3 7 3 7 3 7 11 в качестве результата.
Неважно, что это была моя ошибка, у меня был второй цикл for, работающий внутри первого. Я вытащил его из цикла for и теперь получаю правильные результаты.
Поскольку вы не работаете с функциями шаблона, ваша функция просто использует вектор, итераторы, на мой взгляд, вам не нужны.
Вы могли бы просто иметь что-то вроде
...
for (int i = 0; i < values.size(); i += 2) {
result.push_back(values[i] + values[i + 1]);
}
...
Хорошо, если вы уверены, что values.size() всегда четно.
Если это не так, вы можете сделать что-то вроде
void sumElementPairsFromVector(const std::vector<int>& values, std::vector<int>& result)
{
for (int i = 1; i < values.size(); i += 2) {
result.push_back(values[i] + values[i - 1]);
}
if (values.size() % 2) {
// whatever you want to do with the last element of an uneven vector
result.push_back(values[values.size() - 1]);
}
}
потому что, если вы не уверены, что размер значений всегда четный, первый метод попытается получить доступ к n-му элементу, где n больше, чем количество элементов, поэтому вы можете получить значение мусора.
Я заявил, предполагая, что векторы всегда имеют четную длину. Они не должны использоваться вне этого контекста. Я ценю обратную связь!
Можно ли использовать Ranges v3? Код будет намного понятнее и менее подвержен ошибкам.