Каков правильный подход при использовании контейнера STL для среднего вычисления?

Alt-Shift-R обозначает , переименовывают , не осуществляют рефакторинг. Рефакторинг более общий термин (как определено книга ).

, Тем не менее, это - один из моих любимых рефакторингов. Другие включают:

Локальная переменная Извлечения особенно полезна, когда я не помню (или потрудился вводить), тип результата метода. Принятие Вас имеет метод JdbcTemplate createJdbcTemplate() в Вашем классе, пишет некоторый код, такой как это:

void someQuery() {
    createJdbcTemplate()
}

Выбор выражение createJdbcTemplate(), нажмите Alt-Shift-L, введите имя переменной и нажмите Enter.

void someQuery() {
    JdbcTemplate myTemplate = createJdbcTemplate();
}

40
задан xskxzr 5 June 2019 в 07:25
поделиться

4 ответа

Любой контейнер произвольного доступа (например, std :: vector ) может быть отсортирован с помощью стандартного алгоритма std :: sort , доступного в <алгоритм> заголовок.

Для нахождения медианы было бы быстрее использовать std :: nth_element ; этого достаточно для сортировки одного выбранного элемента в правильное положение, но не для полной сортировки контейнера. Таким образом, вы можете найти медиану следующим образом:

int median(vector<int> &v)
{
    size_t n = v.size() / 2;
    nth_element(v.begin(), v.begin()+n, v.end());
    return v[n];
}
87
ответ дан 27 November 2019 в 01:03
поделиться

Вы можете отсортировать std :: vector с помощью библиотечной функции std :: sort .

std::vector<int> vec;
// ... fill vector with stuff
std::sort(vec.begin(), vec.end());
4
ответ дан 27 November 2019 в 01:03
поделиться

Существует алгоритм выбора линейного времени . Приведенный ниже код работает только тогда, когда в контейнере есть итератор с произвольным доступом, но его можно изменить для работы без него - вам просто нужно быть немного осторожнее, чтобы избежать таких ярлыков, как end - begin и iter + n .

#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <vector>

template<class A, class C = std::less<typename A::value_type> >
class LinearTimeSelect {
public:
    LinearTimeSelect(const A &things) : things(things) {}
    typename A::value_type nth(int n) {
        return nth(n, things.begin(), things.end());
    }
private:
    static typename A::value_type nth(int n,
            typename A::iterator begin, typename A::iterator end) {
        int size = end - begin;
        if (size <= 5) {
            std::sort(begin, end, C());
            return begin[n];
        }
        typename A::iterator walk(begin), skip(begin);
#ifdef RANDOM // randomized algorithm, average linear-time
        typename A::value_type pivot = begin[std::rand() % size];
#else // guaranteed linear-time, but usually slower in practice
        while (end - skip >= 5) {
            std::sort(skip, skip + 5);
            std::iter_swap(walk++, skip + 2);
            skip += 5;
        }
        while (skip != end) std::iter_swap(walk++, skip++);
        typename A::value_type pivot = nth((walk - begin) / 2, begin, walk);
#endif
        for (walk = skip = begin, size = 0; skip != end; ++skip)
            if (C()(*skip, pivot)) std::iter_swap(walk++, skip), ++size;
        if (size <= n) return nth(n - size, walk, end);
        else return nth(n, begin, walk);
    }
    A things;
};

int main(int argc, char **argv) {
    std::vector<int> seq;
    {
        int i = 32;
        std::istringstream(argc > 1 ? argv[1] : "") >> i;
        while (i--) seq.push_back(i);
    }
    std::random_shuffle(seq.begin(), seq.end());
    std::cout << "unordered: ";
    for (std::vector<int>::iterator i = seq.begin(); i != seq.end(); ++i)
        std::cout << *i << " ";
    LinearTimeSelect<std::vector<int> > alg(seq);
    std::cout << std::endl << "linear-time medians: "
        << alg.nth((seq.size()-1) / 2) << ", " << alg.nth(seq.size() / 2);
    std::sort(seq.begin(), seq.end());
    std::cout << std::endl << "medians by sorting: "
        << seq[(seq.size()-1) / 2] << ", " << seq[seq.size() / 2] << std::endl;
    return 0;
}
2
ответ дан 27 November 2019 в 01:03
поделиться

Медиана сложнее, чем ответ Майка Сеймура. Медиана различается в зависимости от того, четное или нечетное количество предметов в выборке. Если элементов четное количество, то медиана - это среднее значение двух средних элементов. Это означает, что медиана списка целых чисел может быть дробью. Наконец, медиана пустого списка не определена. Вот код, который проходит мои основные тесты:

///Represents the exception for taking the median of an empty list
class median_of_empty_list_exception:public std::exception{
  virtual const char* what() const throw() {
    return "Attempt to take the median of an empty list of numbers.  "
      "The median of an empty list is undefined.";
  }
};

///Return the median of a sequence of numbers defined by the random
///access iterators begin and end.  The sequence must not be empty
///(median is undefined for an empty set).
///
///The numbers must be convertible to double.
template<class RandAccessIter>
double median(RandAccessIter begin, RandAccessIter end) 
  throw(median_of_empty_list_exception){
  if(begin == end){ throw median_of_empty_list_exception(); }
  std::size_t size = end - begin;
  std::size_t middleIdx = size/2;
  RandAccessIter target = begin + middleIdx;
  std::nth_element(begin, target, end);

  if(size % 2 != 0){ //Odd number of elements
    return *target;
  }else{            //Even number of elements
    double a = *target;
    RandAccessIter targetNeighbor= target-1;
    std::nth_element(begin, targetNeighbor, end);
    return (a+*targetNeighbor)/2.0;
  }
}
33
ответ дан 27 November 2019 в 01:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: