список фильтров - C ++ - PullRequest
0 голосов
/ 17 мая 2018

Я бы хотел отфильтровать список в C ++. Для этого мне была предоставлена ​​внешняя функция f, которая сравнивает элементы. На основании этого сравнения я решаю, какие элементы оставить.

Кажется, моя реализация неверна, не могли бы вы помочь мне найти ошибку?

Пример для f:

bool function f(a, b){
if (a + b % 3 != 0){
    return true; // keep element
}
return false; }

Я хотел бы подчеркнуть, что это всего лишь пример, чтобы сохранить это простым.

Моя реализация должна работать так (элементы, разделенные ___):

1____2____3____4____5____6____7____8
^    ^
f(1, 2) == false. Discard 2. 

1____3____4____5____6____7____8
^    ^
now compare the next element with 1 
f(1, 3) == true. Keep 3. Move first pointer to 3

1____3____4____5____6____7____8
     ^    ^
Compare 3 with 4 ...

1____3____4____5____6____7____8
          ^    ^
remove 5, since f(4, 5) == false

1____3____4____6____7____8
          ^    ^
keep 6, move pointer 

1____3____4____6____7____8
               ^    ^
1____3____4____6____7____8
                    ^    ^
remove 8. 

1____3____4____6____7
                    ^
Nothing more to compare. Terminate. 

Я реализую «удаление», перемещая допустимые элементы в другой список и перемещая итератор к следующему элементу в исходном списке, но на самом деле их удаление тоже будет в порядке.

list<node> result;
list<node>::iterator i = path.begin();
element firstElement = *i;
result.push_back(firstElement);
for (; i != path.end();)
{
    if (++i == path.end())
    {
        break;
    }
    // compare with next node
    int d = distance(firstElement.id, (*i).id);
    if (d <= (*i).valFrom)
    {
        // add edge to result
        result.push_back(*i);
        firstElement = *i;
    }
}

рабочий пример

#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>
#include <list>

using namespace std;

int f(int a, int b)
{
    if (a + b % 3 == 0)
    {
        return false;
    }
    return true;
}

int main()
{

    list<int> path = {1, 2, 3, 4, 5, 6, 7, 8};
    list<int> result;
    bool skip = false;
    list<int>::iterator i = path.begin();
    int firstint = *i;
    result.push_back(firstint);
    for (; i != path.end();)
    {
        if (++i == path.end())
        {
            break;
        }
        // compare with next int
        if (f(firstint, *i))
        {
            // add edge to result
            result.push_back(*i);
            firstint = *i;
        }
    }

    // output path
    for (list<int>::iterator i = result.begin(); i != result.end(); ++i)
    {
        cout << *i << ' ';
    }
}

1 Ответ

0 голосов
/ 17 мая 2018

я думаю, что вы хотите что-то вроде:

std::list<int> mylist{ 1,2,3,4,5,6,7,8,9,10 };

mylist.remove_if([](auto val)
{
    return ((val % 2) == 1);
});

это удалит все неравные значения из списка

, если вы хотите результаты в другом списке:

std::list<int> mylist{ 1,2,3,4,5,6,7,8,9,10 };
std::list<int> mylistFilered;

std::copy_if(mylist.begin(), mylist.end(), std::back_inserter(mylistFilered),[](auto val)
{
    return ((val % 2) == 1);
});

для фильтра, основанного на 2 последовательных элементах, нам нужен небольшой список помощников.например, вот так:

std::list<int> mylist{ 1,2,3,5,7,4,5,6,7,8,9,10 };
std::list<int> keepElement;
std::list<int> mylistFilered;

std::transform(mylist.begin(), --mylist.end(), ++mylist.begin(), std::back_inserter(keepElement),[](auto a, auto b)
{
    return ((a + b) % 3 != 0);
});

или, если у вас есть, например, можно использовать -1 как недопустимое значение, например:

std::list<int> mylist{ 1,2,3,5,7,4,5,6,7,8,9,10 };
std::list<int> mylistFilered;

std::transform(mylist.begin(), --mylist.end(), ++mylist.begin(), std::back_inserter(mylistFilered),[](auto a, auto b)
{
    if ((a + b) % 3 != 0)
        return a;
    else
        return -1;
});

mylistFilered.remove_if([](auto val)
{
    return (val == -1);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...