Какая в C++ есть альтернатива питоновскому enumerate, чтобы было что-то вроде этого:
# Для каждого элемента в массиве создаём массив с его индексами:
unique = [a, b, c]
array = [a,b,b,a,a,c,a,c,b,a,c,a]
indexes =[]
for j in unique:
indexes.append([i+1 for i, e in enumerate(array) if e == j])
#indexes[0] = [1,4,5,7,10,12] для a
#indexes[1] = [2,3,9] для b
#indexes[2] = [6,8,11] для c
Как можно реализовать точно такой же код для вектора чисел (vector) в C++?
В стандартной библиотеке аналога enumerate нет, но можно сделать свой итератор/диапазон с аналогичной функциональностью. Подобные решения есть в Boost.Range и в range-v3.
В range-v3 это выглядит примерно так (один из вариантов):
#include <array>
#include <map>
#include <vector>
#include <range/v3/all.hpp>
auto foo(int a, int b, int c){
namespace view = ranges::view;
std::array unique = {a, b, c};
std::array array = {a,b,b,a,a,c,a,c,b,a,c,a};
std::map<int, std::vector<std::size_t>> indexes; // Это если опираться на то, что должно выводиться, у вас ожидаемый вывод не совпадает с кодом
for(auto j: unique){
for(auto&& [e, i] : view::zip(array, view::ints(1))){ // аналог enunerate с индексацией от 1)
if(j == e){
indexes[j].push_back(i);
}
}
}
return indexes;
}
#include <iostream>
int main()
{
int a = -5, b = 16, c = 81;
ranges::copy(foo(a,b,c)[a], ranges::ostream_iterator<int>(std::cout, ", "));
std::cout << "\n";
ranges::copy(foo(a,b,c)[b], ranges::ostream_iterator<int>(std::cout, ", "));
std::cout << "\n";
ranges::copy(foo(a,b,c)[c], ranges::ostream_iterator<int>(std::cout, ", "));
std::cout << "\n";
}
В онлайн компиляторе: ссылка
Upd:
Еще есть вариант с filter | transform
, но filter
считается устаревшим и заменён на remove_if
, что менее наглядно (вместо добавления того, что хотим, удаляем то, что не нужно), а необходимость распаковки кортежей делает код довольно плохо читаемым.
И есть более-менее компромиссный вариант:
auto foo(int a, int b, int c){
namespace view = ranges::view;
std::array unique = {a, b, c};
std::array array = {a,b,b,a,a,c,a,c,b,a,c,a};
std::map<int, std::vector<std::size_t>> indexes;
for(auto j: unique){
auto goalRange = view::zip(array, view::ints(1))
| view::for_each([&](auto&& pair){
auto [e, i] = pair;
return ranges::yield_if(e == j, i);
});
ranges::copy(goalRange, ranges::back_inserter(indexes[j]));
}
return indexes;
}
Виртуальный выделенный сервер (VDS) становится отличным выбором
При создании проекта выбрал пустой проект, тк
Имеется DLL C++ скомпилированная на MSVCПри динимической подгрузке DLL инициализируется фабрика и создает класс который используется дальше
Необходимо написать функции перевода вещественных и целых чисел в строку без функцийПервую функцию написал