Для этой проблемы ваше решение является самым простым, называется наивным, когда вы ищете каждый элемент в последовательности или, в вашем случае, интервал для проверки чего-либо или выполнения операций.
Наивный алгоритм
Предполагая, что a и b - положительные целые числа с b больше, чем a, давайте назовем измерение / размер интервала [a, b], n = (ba).
Имея наше количество элементов n и используя некоторые обозначения алгоритмов (например, обозначение большого O, ссылка) , стоимость наихудшего случая составляет O(n*(numberOfBits_cost))
.
Из этого мы видим, что мы можем ускорить наш алгоритм, используя более быстрый алгоритм для вычисления numberOfBits (), или нам нужно найти способ не смотреть на каждый элемент интервала, который стоит нам n операций. .
Интуиция
Теперь, посмотрев на возможный интервал [6,14], вы увидите, что для 6 и 7 нам нужно 3 цифры, при этом 4 необходимо для 8,9,10,11,12,13,14. Это приводит к вызову numberOfBits () для каждого числа, которое использует одинаковое количество цифр для представления, тогда как следующая операция умножения будет быстрее:
(number_in_subinterval)*digitsForThisInterval
((14-8)+1)*4 = 28
((7-6)+1)*3 = 6
Таким образом, мы сократили цикл на 9 элементах с 9 операциями до 2.
Таким образом, написание функции, использующей эту интуицию, даст нам более эффективный во времени, а не обязательно в памяти, алгоритм. Используя вашу функцию numberOfBits (), я создал это решение:
int intuitionSol(int a, int b){
int digitsForA = numberOfBits(a);
int digitsForB = numberOfBits(b);
if(digitsForA != digitsForB){
//because a or b can be that isn't the first or last element of the
// interval that a specific number of digit can rappresent there is a need
// to execute some correction operation before on a and b
int tmp = pow(2,digitsForA) - a;
int result = tmp*digitsForA; //will containt the final result that will be returned
int i;
for(i = digitsForA + 1; i < digitsForB; i++){
int interval_elements = pow(2,i) - pow(2,i-1);
result = result + ((interval_elements) * i);
//printf("NumOfElem: %i for %i digits; sum:= %i\n", interval_elements, i, result);
}
int tmp1 = ((b + 1) - pow(2,digitsForB-1));
result = result + tmp1*digitsForB;
return result;
}
else {
int elements = (b - a) + 1;
return elements * digitsForA; // or digitsForB
}
}
Давайте посмотрим на стоимость. Стоимость этого алгоритма - это стоимость выполнения операции коррекции для a и b плюс самая дорогая операция цикла for. Однако в моем решении я не перебираю все элементы, а только numberOfBits(b)-numberOfBits(a)
, который в худшем случае, когда [0, n] становится log (n) -1 это эквивалентно O (log n). Чтобы продолжить, мы перешли от линейной стоимости операций O (n) к логарифмической стоимости O (log n) в худшем случае. Посмотрите на эту диаграмму различия между ними.
Примечание
Когда я говорю об интервале или подинтервале, я имею в виду интервал элементов, которые используют одинаковое количество цифр для представления числа в двоичном формате. Ниже приведены некоторые результаты моих тестов с последним, которые показывают разницу:
Considered interval is [0,4]
YourSol: 9 in time: 0.000015s
IntuitionSol: 9 in time: 0.000007s
Considered interval is [0,0]
YourSol: 1 in time: 0.000005s
IntuitionSol: 1 in time: 0.000005s
Considered interval is [4,7]
YourSol: 12 in time: 0.000016s
IntuitionSol: 12 in time: 0.000005s
Considered interval is [2,123456]
YourSol: 1967697 in time: 0.005010s
IntuitionSol: 1967697 in time: 0.000015s
person
Iulian
schedule
05.11.2018
unsigned
. - person chux - Reinstate Monica   schedule 04.11.2018Effective
: получение желаемого эффекта. Похоже, вас интересует эффективный: получение эффекта с разумными усилиями.sequence of integers
может быть (911, 13, 42, 13) - похоже, вы используете interval.) - person greybeard   schedule 05.11.2018