Как понять, когда использовать оператор модуля

Я знаю, что оператор модуля (%) вычисляет остаток от деления. Как я могу определить ситуацию, в которой мне нужно будет использовать оператор модуля?

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

У меня просто проблемы с определением того, где применим оператор модуля. В различных ситуациях программирования мне трудно увидеть проблему и осознать: «Эй! Здесь сработает остаток деления!».


person Codebug    schedule 09.04.2010    source источник
comment
По сути, он используется для повторения времени, дат и последовательности.   -  person Donato    schedule 19.07.2016


Ответы (19)


Представьте, что у вас есть прошедшее время в секундах, и вы хотите преобразовать его в часы, минуты и секунды:

h = s / 3600;
m = (s / 60) % 60;
s = s % 60;
person Paul R    schedule 09.04.2010

0 % 3 = 0;
1 % 3 = 1;
2 % 3 = 2;
3 % 3 = 0;

Вы видели, что он сделал? На последнем этапе он вернулся к нулю. Это можно использовать в таких ситуациях, как:

  1. Чтобы проверить, делится ли N на M (например, нечетное или четное) или N кратно M.

  2. Ставить шапку определенного значения. В этом случае 3.

  3. Чтобы получить последние M цифр числа -> N% (10 ^ M).
person SysAdmin    schedule 09.04.2010
comment
Вы можете объяснить ситуацию номер 3? Чтобы получить последние M цифр числа - ›N% (10 ^ M). - person Ka Mok; 20.08.2016
comment
Например, в шоколадном рождественском календаре, который делится на 3 человека. Анна может открыть дверцу / окно календаря в первый день (1) и съесть шоколад, Бен во второй день и Карл в третий день, затем снова Анна и так далее. Сделайте «день% 3», и когда результат будет 1: Анна, 2: Бен, 0: Карл. Каждый получает свой шоколад без больших вычислений. - person JonyD; 14.12.2016

Я использую его для индикаторов прогресса и тому подобного, чтобы отмечать прохождение большого цикла. О прогрессе сообщается только каждый n-й раз в цикле или при подсчете% n == 0.

person SeaDrive    schedule 09.04.2010
comment
Значит, ты тоже? Это действительно имеет большое значение в скорости. - person Kawa; 13.04.2010
comment
Это действительно так. Для еще более быстрой версии мне нравится использовать битовую логику: count & 0xff == 0 (вы можете использовать 0xf или 0xff или 0xfff или что-то в этом роде: точка имеет число, которое в двоичном формате представляет собой сплошную строку из единиц) - person Tobia; 11.02.2013

Я использовал его при ограничении числа до определенного кратного:

temp = x - (x % 10); //Restrict x to being a multiple of 10
person Bob    schedule 09.04.2010
comment
Можете ли вы дать этому практическое применение? - person Ka Mok; 20.08.2016

  • Обертывание значений (как часы).
  • Предоставьте конечные поля для алгоритмов с симметричным ключом.
  • Побитовые операции.

И так далее.

person jweyrich    schedule 09.04.2010

Пример. У вас есть сообщение размером X байтов, но в вашем протоколе максимальный размер Y и Y ‹X. Попробуйте написать небольшое приложение, которое разбивает сообщение на пакеты, и вы столкнетесь с модом :)

person Andrey    schedule 09.04.2010

Недавно я увидел один вариант использования, когда вам нужно поменять местами число. Так, например, 123456 становится 654321.

int number   = 123456;
int reversed = 0;

while ( number > 0 ) {
    # The modulus here retrieves the last digit in the specified number
    # In the first iteration of this loop it's going to be 6, then 5, ...
    # We are multiplying reversed by 10 first, to move the number one decimal place to the left.
    # For example, if we are at the second iteration of this loop, 
    #  reversed gonna be 6, so 6 * 10 + 12345 % 10 => 60 + 5
    reversed = reversed * 10 + number % 10;
    number = number / 10;
}
person jonathancardoso    schedule 14.02.2017

Есть много примеров, когда это полезно.

Если вам нужно ограничить число определенным диапазоном, вы можете использовать мод. Например, чтобы сгенерировать случайное число от 0 до 99, вы можете сказать:

num = MyRandFunction() % 100;
person Justin Ethier    schedule 09.04.2010
comment
-1. Это приведет к неоднородным результатам, если 100 не является делителем диапазона MyRandFunction(). (Представьте, что вам нужны случайные числа в 0 .. RAND_MAX*2/3.) - person kennytm; 09.04.2010
comment
@KennyTM: +1. Что, вероятно, было бы лучше, так это иметь возможность передать 100 в MyRandFunction (), которая позаботится об этом должным образом. Плюс это обеспечивает лучшую инкапсуляцию и гораздо более слабую связь. - person Cam; 10.04.2010
comment
Проголосовали за еще один распространенный вариант использования. (вопрос не в генерации криптографических звуков PSRN) - person danecando; 12.10.2015

Каждый раз, когда у вас есть деление и вы хотите выразить остаток не в десятичном виде, подходит оператор mod. Обычно в голову приходят вещи, когда вы хотите сделать что-то удобочитаемое с остатком. Перечислить, сколько предметов вы можете положить в ведра, и сказать «5 осталось» - это хорошо.

Кроме того, если вы когда-нибудь окажетесь в ситуации, когда у вас могут возникнуть ошибки округления, деление по модулю подойдет. Например, если вы делите на 3 довольно часто, вы не хотите передавать 0,33333 в качестве остатка. Уместно передать остаток и делитель (т.е. дробь).

person Matt    schedule 09.04.2010

Как говорит @jweyrich, обертывание значений. Я нашел мод очень удобным, когда у меня есть конечный список, и я хочу перебирать его в цикле - например, фиксированный список цветов для некоторых элементов пользовательского интерфейса, таких как серии диаграмм, где я хочу, чтобы все серии были разными, чтобы насколько это возможно, но когда у меня заканчиваются цвета, просто чтобы начать сначала. Это также можно использовать, скажем, с узорами, так что второй раз, когда появляется красный цвет, он отображается пунктирной линией; в третий раз, с точками и т. д. - но мод просто используется, чтобы получить красный, зеленый, синий, красный, зеленый, синий, навсегда.

person Carl Manaster    schedule 09.04.2010

Модуль может быть полезен для преобразования и разделения общих минут на «часы и минуты»:

часы = минуты / 60

minutes_left = минут% 60

В битах часов нам нужно удалить десятичную часть, и это будет зависеть от используемого вами языка.

Затем мы можем соответствующим образом изменить порядок вывода.

person tony    schedule 02.08.2014
comment
Мы также можем использовать модуль, чтобы определить, является ли год високосным, поскольку он делится на 4. Пример в JS: if (year% 4 === 0) {// это високосный год}. (Примечание: более точная проверка также подтвердит делимость на 100 и 400) - person tony; 05.08.2014

Преобразование линейной структуры данных в матричную структуру: где a - индекс линейных данных, а b - количество элементов в строке:

row = a/b
column = a mod b

Примечание выше представляет собой упрощенную логику: a должен быть смещен на -1 перед делением, а результат должен быть нормализован на +1.

Пример: (3 ряда по 4 шт.)

1  2  3  4    
5  6  7  8    
9 10 11 12 

(7 - 1)/4 + 1 = 2

7 is in row 2

(7 - 1) mod 4 + 1 = 3 

7 is in column 3

Другое распространенное использование модуля: хеширование числа по месту. Предположим, вы хотите сохранить год и месяц в виде шестизначного числа 195810. month = 195810 mod 100 все цифры, третья справа, делятся на 100, поэтому остаток - это 2 крайние правые цифры, в этом случае месяц равен 10. Чтобы извлечь год 195810 / 100, получается 1958.

person Joe    schedule 25.05.2016
comment
Почему нужно компенсировать на 1? - person Ka Mok; 20.08.2016

Расчет простых чисел

person anonymous    schedule 09.04.2010
comment
Хотя я действительно не нашел ситуации, когда мне действительно нужно было их вычислить. - person anonymous; 09.04.2010

Модуль также очень полезен, если по какой-то безумной причине вам нужно сделать целочисленное деление и получить десятичную дробь, и вы не можете преобразовать целое число в число, которое поддерживает десятичное деление, или если вам нужно вернуть дробь вместо десятичной. .

Я буду использовать % в качестве оператора модуля

Например

2/4 = 0

где это делается

2/4 = 0 and 2 % 4 = 2

Итак, вы можете быть действительно сумасшедшим и допустим, что вы хотите разрешить пользователю вводить числитель и делитель, а затем показывать им результат в виде целого числа, а затем дробного числа.

whole Number = numerator/divisor
fractionNumerator = numerator % divisor
fractionDenominator = divisor

Другой случай, когда деление по модулю полезно, - это если вы увеличиваете или уменьшаете число и хотите, чтобы число соответствовало определенному диапазону чисел, но когда вы добираетесь до вершины или низа, вы не хотите просто останавливаться. Вы хотите перейти в конец или вверх по списку соответственно.

Представьте себе функцию, в которой вы просматриваете массив.

Function increase Or Decrease(variable As Integer) As Void
    n = (n + variable) % (listString.maxIndex + 1)  
    Print listString[n]
End Function

Причина, по которой это n = (n + variable)% (listString.maxIndex + 1), заключается в том, чтобы учесть максимальный индекс.

Это лишь некоторые из вещей, для которых мне пришлось использовать модуль при программировании не только настольных приложений, но и в средах робототехники и моделирования.

person msarchet    schedule 09.04.2010

  • Вычисление наибольшего общего делителя
  • Определение того, является ли число палиндромом
  • Определение того, состоит ли число только из ...
  • Определение количества ... числа состоит из ...
person helpermethod    schedule 09.04.2010

Мое любимое использование - итерация.

Предположим, у вас есть счетчик, который вы увеличиваете, и вы хотите извлечь из известного списка соответствующие элементы, но у вас есть только n элементов на выбор, и вы хотите повторить цикл.

var indexFromB = (counter-1)%n+1;

Результаты (counter=indexFromB) для n=3:

`1=1`
`2=2`
`3=3`
`4=1`
`5=2`
`6=3`
...
person Nateous    schedule 17.10.2016

Лучшее использование оператора модуля, которое я видел, - это проверить, является ли массив, который у нас есть, повернутой версией исходного массива.

A = [1,2,3,4,5,6] B = [5,6,1,2,3,4]

Как теперь проверить, является ли B повернутой версией A?

Шаг 1: Если длина A не совпадает с длиной B, то наверняка это не повернутая версия.

Шаг 2: Проверьте индекс первого элемента A в B. Здесь первый элемент A равен 1. А его индекс в B равен 2 (при условии, что ваш язык программирования имеет индекс, отсчитываемый от нуля). позволяет сохранить этот индекс в переменной "Key"

Шаг 3: Теперь, как проверить, что если B повернута версия A, как ??

Вот где скала функция модуля:

for (int i = 0; i< A.length; i++)
{

// here modulus function would check the proper order. Key here is 2 which we recieved from Step 2
   int j = [Key+i]%A.length;

   if (A[i] != B[j])
   {
     return false;
   }
}

return true;
person Vikas Radhakrishna Shetty    schedule 22.07.2018

Это простой способ определить, четное или нечетное число. Просто выполните # mod 2, если 0 - четно, 1 - нечетно.

person user1671033    schedule 18.04.2017

Часто в цикле вы хотите что-то делать на каждой k-й итерации, где k равно 0 ‹k‹ n, предполагая, что 0 - это начальный индекс, а n - длина цикла.

Итак, вы бы сделали что-то вроде:

int k = 5;
int n = 50;
for(int i = 0;i < n;++i)
{
    if(i % k == 0)  // true at 0, 5, 10, 15..
    {
        // do something
    }
}

Или вы хотите сохранить что-то в определенных пределах. Помните, что когда вы берете произвольное число для модификации чего-либо, оно должно давать значение от 0 до этого числа - 1.

person Áron Pop Adorján    schedule 29.08.2020