У меня есть 2D-вектор, и я хочу удалить некоторые его строки. Исходный вектор выглядит так:
Отметьте Вкл./Выкл. Примечание Фон Вофф Длительность
245 144 64 62 64 1132
261 144 41 73 64 1197
272 144 69 116 64 1108
293 144 72 102 64 1060
1353 128 72 64
1377 128 64 64
1380 128 69 64
1458 128 41 64
1519 144 40 83 64 1321
1519 144 62 83 64 1176
1547 144 68 93 64 1167
1564 144 72 116 64 1135
2695 128 62 64
2699 128 72 64
2714 128 68 64
2819 144 60 79 64 1294
2840 128 40 64
2857 144 45 89 64 1322
2874 144 67 97 64 1204
2905 144 71 112 64 1173
4078 128 67 64
4078 128 71 64
4113 128 60 64
4179 128 45 64
У меня есть некоторые проблемы, чтобы сделать это.
Я попытался использовать код:
void DeleteNoteOff(std::vector<std::vector<int> > &eventStore){
for(int i = 0; i<eventStore.size(); i++){
if (eventStore[i][1] == 128){
eventStore.erase(eventStore.begin()+i);
}
}
}
Результат не удаляется полностью.
Отметьте Вкл./Выкл. Примечание Фон Вофф Длительность
245 144 64 62 64 1132
261 144 41 73 64 1197
272 144 69 116 64 1108
293 144 72 102 64 1060
1377 128 64 64
1458 128 41 64
1519 144 40 83 64 1321
1519 144 62 83 64 1176
1547 144 68 93 64 1167
1564 144 72 116 64 1135
2699 128 72 64
2819 144 60 79 64 1294
2857 144 45 89 64 1322
2874 144 67 97 64 1204
2905 144 71 112 64 1173
4078 128 71 64
4179 128 45 64
Нужна помощь!
Я хочу удалить все строки со вторым элементом "128".
И вы разместили небольшой фрагмент кода, который не показывает весь ваш код. Ваш вопрос, вероятно, будет закрыт, если вы не опубликуете минимальный воспроизводимый пример, который можно скомпилировать.





Вы также увеличиваете i на каждой итерации при удалении элемента, чего не должно происходить (поскольку это приводит к пропуску некоторых векторов, содержащих 128. Точнее, это пропустит 2-е, 4-е, 6-е последовательное появление - как это происходит). Используйте это вместо этого:
void DeleteNoteOff(std::vector<std::vector<int> > &eventStore) {
for(int i = 0; i<eventStore.size(); ) {
if (eventStore[i][1] == 128) {
eventStore.erase(eventStore.begin()+i);
}
else {
i++;
}
}
}
Я удалил приращение i++, чтобы оно выполнялось только тогда, когда ни один элемент не стерт.
I wanna delete all the rows with "128" as the second element.
Для этого не нужно писать цикл.
Удаление всех элементов из вектора, удовлетворяющих определенным критериям, может быть выполнено с помощью алгоритма std::remove_if / std::remove вместе с vector::erase:
#include <iostream>
#include <vector>
#include <algorithm>
void DeleteNoteOff(std::vector<std::vector<int> > &eventStore)
{
eventStore.erase(std::remove_if (eventStore.begin(), eventStore.end(),
[](const std::vector<int>& v) {return v.size() > 1 && v[1] == 128;}),
eventStore.end());
}
int main()
{
std::vector<std::vector<int>> test = {{245,144,64,62,64,1132},
{261,144,41,73,64,1197},
{272,144,69,116,64,1108},
{293,144,72,102,64,1060},
{1353,128,72,64},
{1377,128,64,64},
{1380,128,69,64},
{1458,128,41,64},
{1519,144,40,83,64,1321},
{1519,144,62,83,64,1176},
{1547,144,68,93,64,1167},
{1564,144,72,116,64,1135},
{2695,128,62,64},
{2699,128,72,64},
{2714,128,68,64},
{2819,144,60,79,64,1294},
{2840,128,40,64},
{2857,144,45,89,64,1322},
{2874,144,67,97,64,1204},
{2905,144,71,112,64,1173},
{4078,128,67,64},
{4078,128,71,64},
{4113,128,60,64},
{4179,128,45,64}};
DeleteNoteOff(test);
for (auto& v : test)
{
std::cout << "{";
for (auto& v2 : v)
std::cout << v2 << " ";
std::cout << "}\n";
}
}
Выход:
{245 144 64 62 64 1132 }
{261 144 41 73 64 1197 }
{272 144 69 116 64 1108 }
{293 144 72 102 64 1060 }
{1519 144 40 83 64 1321 }
{1519 144 62 83 64 1176 }
{1547 144 68 93 64 1167 }
{1564 144 72 116 64 1135 }
{2819 144 60 79 64 1294 }
{2857 144 45 89 64 1322 }
{2874 144 67 97 64 1204 }
{2905 144 71 112 64 1173 }
Краткое объяснение:
std::remove_if перемещает все элементы, которые необходимо удалить, в конец вектора eventStore. Возвращаемое значение std::remove_if — это итератор начала удаленных элементов.
Критерий remove_if задается лямбда-функцией, которая принимает отдельный внутренний вектор и проверяет, равно ли второе значение в векторе 128 (обратите внимание на проверку, чтобы убедиться, что вектор имеет как минимум 2 элемента). Если возвращаемое значение лямбда-функции равно true, то этот вектор будет «удален» (т. е. перемещен в конец eventStore).
Затем, наконец, eventStore.erase берет это возвращаемое значение из remove_if и стирает все элементы, начиная с того места, где начинаются перемещенные (удаленные) элементы, до конца вектора.
Укажите минимальный воспроизводимый пример с вводом и желаемым выводом.