Важная вещь здесь состоит в том, чтобы изменить систему, чтобы удалить загрузку из Вашего сервера, препятствовать тому, чтобы боты выиграли мешок дерьма, не позволяя botlords знать, что Вы играете их, или они пересмотрят свою стратегию. Я не думаю, что существует любой способ сделать это без некоторой обработки в Вашем конце.
, Таким образом, Вы записываете хиты на своей домашней странице. Каждый раз, когда кто-то поражает страницу, что соединение сравнивается со своим последним хитом, и если это было слишком быстро затем, это отправляется версию страницы без предложения. Это может быть сделано своего рода механизмом выравнивания нагрузки, который отправляет ботов (хиты, которые слишком быстры) к серверу, который просто служит кэшированным версиям Вашей домашней страницы; настоящие люди отправляются на хороший сервер. Это берет загрузку от основного сервера и заставляет ботов думать, что они все еще подаются страницы правильно.
Еще лучше, если предложение может быть отклонено в некотором роде. Затем можно все еще сделать предложения относительно декоративного сервера, но когда бот заполняет форму, говорят "Извините, что Вы не были достаточно быстры" :) Затем они будут определенно думать, что находятся все еще в игре.
Я могу придумать несколько возможных решений более общей проблемы, когда диапазоны неоднородны и есть «дыры». Самыми простыми из них являются:
floorEntry (ключ)
для поиска. Это должно быть менее затратным по времени (O (поиск в журнале (N)), но более эффективным для использования места. Вот решение с использованием NavigableMaps, которое позволяет «дыры» в отображении.
private static class Range {
public int upper, value;
...
}
NavigableMap<Integer, Range> map = new TreeMap<Integer, Range>();
map.put(0, new Range(3, 0)); // 0..3 => 0
map.put(5, new Range(10, 1)); // 5..10 => 1
map.put(100, new Range(200, 2)); // 100..200 => 2
// To do a lookup for some value in 'key'
Map.Entry<Integer,Range> entry = map.floorEntry(key);
if (entry == null) {
// too small
} else if (key <= entry.getValue().upper) {
return entry.getValue().value;
} else {
// too large or in a hole
}
С другой стороны, если нет 'дыры' решение проще:
NavigableMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
map.put(0, 0); // 0..4 => 0
map.put(5, 1); // 5..10 => 1
map.put(11, 2); // 11..200 => 2
// To do a lookup for some value in 'key'
if (key < 0 || key > 200) {
// out of range
} else {
return map.floorEntry(key).getValue();
}
Псевдокод:
new int [] {0, 3, 5, 15, 100, 300}
. Arrays.binarySearch ()
. 10
в приведенном выше массиве будет 3
, помещая его между 5
и 15
, поэтому он принадлежит во втором диапазоне. В более общем случае, который не может быть решен с помощью арифметики, вы можете создать TreeMap с соответствующим компаратором. Добавьте сопоставления для граничных значений, а затем используйте потолокEntry или floorEntry, чтобы найти подходящее соответствие.
Я думаю, что вам нужно что-то вроде foo () / 10
, но это даст вам несколько отклонений от того, что вы просили. Вы всегда можете просто сравнить две конечные точки для каждого элемента вашей «карты», если они не следуют простой схеме.
Я думаю, что самым простым решением было бы добавить сопоставления от верхних границ ваших диапазонов к значению, которое соответствует диапазону, и просто продолжать увеличивать свое число (нажмите на карте), пока не достигнете отображение (которое является верхней границей диапазона, в котором находится ваш номер).
Другой способ - заполнить карту всеми записями в диапазоне и добавить сопоставление для каждой.
Какой из них более эффективен зависит от того, нужно ли вам запрашивать все числа в диапазоне повторно (используйте второе решение) или несколько раз только некоторые числа (используйте первое)