Собственно суть проблемы:
При выполнении выдает ошибку:
Expression: vector iterator not incrementable. For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.
Проблема в этой строке : arr.erase(it);
Как исправить эту ошибку?
void DeleteZeros(std::vector<int>&arr)
{
for (std::vector<int>::iterator it = arr.begin(); it != arr.end(); ++it)
{
if (*it == 0)
{
arr.erase(it);
}
else
{
std::cout << "asdasdasd"<< std::endl;
}
}
}
Код:
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
//using namespace std;
void MakeArr(std::vector<int>&arr)
{
for (int i = 0; i < arr.size(); i++)
{
arr[i]= rand() % 10;
}
}
void show_vector(std::vector<int>&a)
{
for (std::vector<int>::iterator it = a.begin(); it != a.end(); ++it)
std::cout << *it<<" ";
}
int*GetFreq1(int*arr, int size)
{
int*FreqArr=new int[size];
for (int i = 0; i < size; i++)
{
int Count = 1;
for (int j = i + 1; j < size; j++)
{
if (arr[i] == arr[j])
{
Count++;
FreqArr[j] = 0;
}
}
if (FreqArr[i] != 0)
{
FreqArr[i] = Count;
}
}
std::cout << "\n Frequency of All the Elements in this Array are : \n" << std::endl;
for (int i = 0; i < size; i++)
{
if (FreqArr[i] != 0)
{
std::cout << arr[i] << "occurs" << FreqArr[i] << "times" << std::endl;
}
}
return FreqArr;
}
void DeleteZeros(std::vector<int>&arr)
{
for (std::vector<int>::iterator it = arr.begin(); it != arr.end(); ++it)
{
if (*it == 0)
{
arr.erase(it); //iterator is not incrementable
//std::cout << "blyaa";
}
}
}
int main()
{
int n;
std::cout << "input count of elements :";
std::cin>>n;
std::vector<int>arr(n);
std::vector<int>n_i(n);
MakeArr(arr);
show_vector(arr);
std::sort(arr.begin(), arr.end()); //variazijnyj ryad
std::cout <<std::endl<<"Sorted Arr :" << std::endl;
show_vector(arr);
//n_i=getFreq(arr, n);
int*sss = new int[n];
int*atatat = new int[n];
for (int i = 0; i < arr.size(); i++)
{
atatat[i] = arr[i];
}
sss = GetFreq1(atatat, n);
for(int i=0;i<arr.size();i++)
{
n_i[i] = sss[i];
}
//std::unique(arr.begin(), arr.end());// building a table
std::cout << "\n N-i table: " << std::endl;
show_vector(n_i);
DeleteZeros(n_i);
show_vector(n_i);
system("pause");
return 0;
}
Вообще-то у вас при выполнении arr.erase(it)
итератор инвалидируется, и продолжать работать с ним нельзя, о чем так и пишется в описании erase()
:
Invalidates iterators and references at or after the point of the erase, including the end()
iterator.
Для понимания - представьте ситуацию, когда вы удаляете единственный элемент вектора - сразу после этого, даже если никакого переноса элементов не будет, вы получите, что итератор уже указывает за массив - в arr.end()
. А вы собираетесь его еще и увеличить, а потом сравнить с arr.end()
- во-первых, он будет не равен, и вы получаете бесконечный цикл, во-вторых, начинаете проверять элементы все дальше и дальше за границами массива... Так понятнее?
Кроме того, erase()
по одному элементу - процедура дорогостоящая.
Так что замените некорректное решение на, например, такое - с использованием стандартного алгоритма remove()
:
void DeleteZeros(std::vector<int>&arr)
{
arr.erase(remove(arr.begin(),arr.end(),0),arr.end());
}
Это не ответ на заданный вами вопрос, но очень хотелось отметить, что нужно выбирать путь проще при написании кодов, используя больше инструментов, предаставленных стандартом. Вот, например, можно упростить весь ваш код до такого:
int n;
std::cout << "input count of elements : ";
std::cin>>n;
std::vector<int>arr(n);
for (int& i : arr)
i = rand() % 10;
std::map<int, int> m_i;
for (const int i : arr) {
std::cout << i << ' ';
m_i[i]++;
}
std::cout << std::endl;
std::cout << "\n Frequency of All the Elements in this Array are : \n\n";
for (auto p : m_i)
std::cout << p.first << " occurs " << p.second << " times\n" ;
std::cout << " N-i table: \n";
for (auto p : m_i)
std::cout << p.second <<' ';
Без всяких сложностей с определениями функций и фигурирования массивов. Тут конечно можно еще уменьшить количество строк, если использовать стандартные альгоритмы и лямбда выражения, но такой вариант не хуже...
Само собой у вас выдает ошибку, смотрите сюда:
for (std::vector<int>::iterator it = arr.begin(); it != arr.end(); ++it)
{
if (*it == 0)
{
arr.erase(it);
видите, вы удаляете итератор, а что потом? А потом вы берете его, и увеличиваете в for
, делаете ++it
Чтобы исправить сделайте так (проверено):
void DeleteZeros(std::vector<int>&arr)
{
for (std::vector<int>::iterator it = arr.begin(); it != arr.end();)
{
if (*it == 0)
{
arr.erase(it);
}
else
{
++it;
}
}
}
Таким образом после удаления for
будет проверять можно ли увеличивать итеротор (тобишь не указывает ли он на конец). Правда если будете удалять несколько, а не один, это все равно приведет к проблеме.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Есть ли в классе Pawn функционал для отслеживания событий мыши, клавиатуры по конкретному мешу внутри Pawn?
Я бы хотел разобраться в том, каким образом названные функции реализуют сохранение информации о последней возникшей ошибке в текущем вызывающем...
Необходимо создать wav файл в котором будут сохранены дорожки нескольких wav файлаМожно посоветовать и библиотеку которая занимается этим...