Заполнить структуру при поиске min_element, C++

Я хочу заполнить некоторую структуру, находя минимальный элемент. Пожалуйста, найдите код ниже

tyoedef struct Point
{
    double x, y;
}Point;

у меня есть vector of points - std::vector<Point> V в котором у меня есть несколько тысяч очков.

У меня есть еще одна структура

typedef struct cart
{
    Point pt;
    double val_1; // computed using only Pt
    double val_2; // computer using only Pt
}cart;

Теперь у меня есть две задачи:

  1. Мне нужно найти минимальный элемент из структуры V.
  2. Заполните структуру тележки, которая напрямую зависит от V.

    Я могу сделать это, используя следующий код.

    std::vector<cart> vCart;
    for(unsigned i = 0; i < V.size(); ++i)
    {
        cart thsElement;
        thsElement.pt = V[i];
        thsElement.val_1 = compute_val_1(V[i]);
        thsElement.val_2 = compute_val_2(V[i]);
        vCart.push_back(thsElement)
    }
    
    auto it = std::min_element(vCart.begin(), vCart.end(), lex_sort);
    
    bool lex_sort(cart const &a, cart const &b)
    {
        if(a.pt.x < b.pt.x) return true;
        if(a.pt.x == b.pt.x) return (a.pt.y < b.pt.y);
    }
    

Теперь есть очевидная проблема с этой реализацией.

Есть две петли. Один для заполнения структуры, другой для поиска элемента min (std::min_element() должен иметь цикл для перебора всех значений). Я борюсь за улучшение нескольких миллисекунд. Так что это не хороший код. Более того, это выглядит так C_style

Поэтому я придумал следующий код.

    std::vector<cart> vCart;
    std::iterator <vCart> st_ite;

    auto it = std::min_element(V.begin(), V.end(), boost::bind(FillStruct_LexSort, st_ite, _1, _2)); // V is a vector of Point

    bool FillStruct_LexSort(std::insert_iterator< std::vector<Cart>> vcpInput, const Point &a, const Point &b)
    {
        Cart thsPt;
        if(a.x() < b.x())
        {
            thsPt.pt = b;
            thsPt.val_1 = compute_val_1(b);
            thsPt.val_2 = compute_val_2(b);
            (*vcpInput++) = (thsPt);
            return true;
        }
        if (a.x() == b.x())
        {
            if(a.y() < b.y())
            {
                thsPt.pt = b;
                thsPt.val_1 = compute_val_1(b);
                thsPt.val_2 = compute_val_2(b);

                (*vcpInput++) = (thsPt);
                return true;
            }
        }

        thsPt.pt = a;
        thsPt.val_1 = compute_val_1(b);
        thsPt.val_2 = compute_val_2(b);

        (*vcpInput++) = (thsPt);
        return false;
    }

Теперь проблема в том, что я получил ошибку сегментации. Я не знаю, как я должен использовать итератор для вставки значения. Я попытался передать ссылку на vCart, но vCart пусто после вызова min_element (..). Я даже попробовал insert_iterator, но безуспешно.

Так пож, предложите.

1 ответ

Решение

Кажется, вы хотите что-то вроде:

bool lex_sort(const Point& lhs, const Point& rhs)
{
    return std::tie(lhs.x, lhs.y) < std::tie(rhs.x, rhs.y);
}

а потом

auto it = std::min_element(V.begin(), V.end(), &lex_sort);
if (it == V.end()) {
    // V is empty.
} else {
    Cart thsPt;
    thsPt.pt = it;
    thsPt.val_1 = compute_val_1(*it);
    thsPt.val_2 = compute_val_2(*it);
    return thsPt;
}

Обратите внимание, что если val_1/val_2 всегда зависит от ptВы можете добавить конструктор для Cart которые принимают Point

Другие вопросы по тегам