Alt-Shift-R обозначает , переименовывают , не осуществляют рефакторинг. Рефакторинг более общий термин (как определено книга ).
, Тем не менее, это - один из моих любимых рефакторингов. Другие включают:
Alt-Shift-M: Метод Извлечения (когда блок кода или выражение выбраны)
Alt-Shift-L: Локальная переменная Извлечения (когда выражение выбрано)
Локальная переменная Извлечения особенно полезна, когда я не помню (или потрудился вводить), тип результата метода. Принятие Вас имеет метод JdbcTemplate createJdbcTemplate()
в Вашем классе, пишет некоторый код, такой как это:
void someQuery() {
createJdbcTemplate()
}
Выбор выражение createJdbcTemplate()
, нажмите Alt-Shift-L, введите имя переменной и нажмите Enter.
void someQuery() {
JdbcTemplate myTemplate = createJdbcTemplate();
}
Любой контейнер произвольного доступа (например, 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];
}
Вы можете отсортировать std :: vector
с помощью библиотечной функции std :: sort
.
std::vector<int> vec;
// ... fill vector with stuff
std::sort(vec.begin(), vec.end());
Существует алгоритм выбора линейного времени . Приведенный ниже код работает только тогда, когда в контейнере есть итератор с произвольным доступом, но его можно изменить для работы без него - вам просто нужно быть немного осторожнее, чтобы избежать таких ярлыков, как 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;
}
Медиана сложнее, чем ответ Майка Сеймура. Медиана различается в зависимости от того, четное или нечетное количество предметов в выборке. Если элементов четное количество, то медиана - это среднее значение двух средних элементов. Это означает, что медиана списка целых чисел может быть дробью. Наконец, медиана пустого списка не определена. Вот код, который проходит мои основные тесты:
///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;
}
}