识别何时使用取模运算符

71

我知道modulus(%)运算符计算除法的余数。我如何确定需要使用模运算符的情况?

我知道我可以使用模运算符来查看一个数字是偶数还是奇数,是质数还是合数,但仅此而已。我不经常考虑余数。我相信模运算符很有用,我想学会利用它。

我只是有问题识别模运算符适用的地方。在各种编程情况下,我很难看到问题并意识到“嘿!这里可以用除法的余数!”。


基本上,它用于时间、日期和序列重复。 - Daniel Viglione
19个回答

4

将线性数据结构转换为矩阵结构: 其中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中存储年份和月份。月份 = 195810 mod 100,从右数第三个数字都可以被100整除,因此余数是最右边的2个数字,在这种情况下月份是10。要提取年份,195810 / 100得到1958。


2
为什么必须偏移1? - Ka Mok

4

质数的计算


8
虽然我并没有真正遇到需要计算它们的情况。 - anonymous
素数和模运算在古典密码学中被广泛使用。 - CodeSamurai-like

4

取模运算可以将总分钟数转换并拆分为"小时和分钟":

小时 = 分钟 / 60

剩余分钟数 = 分钟 % 60

在小时部分,我们需要去除小数部分,这将取决于您使用的语言。

然后我们可以相应地重新排列输出。


我们也可以使用模运算来判断一个年份是否为闰年,因为它可以被4整除。JS示例:if (year % 4 === 0) { // it's a leap year }。(注意:更准确的检查还将验证能否被100和400整除) - tony

3

如果你需要进行整数除法并得到小数,而又无法将整数转换为支持小数除法的数字,或者需要返回分数而不是小数,那么取模运算符也非常有用。

我将使用%作为取模运算符

例如

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) 的原因是为了考虑到最大索引。

这些只是我在编写桌面应用程序、机器人和仿真环境时使用模数的一些例子。


2

我最喜欢的用途是迭代。

比如说你有一个计数器在不停地增加,然后想从已知列表中获取相应的项。但你只有 n 个选项可供选择,而且还想重复循环。

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

n=3 时,结果为 (counter=indexFromB):

`1=1`
`2=2`
`3=3`
`4=1`
`5=2`
`6=3`
...

2

我见过使用模运算符最好的方法是检查我们拥有的数组是否是原始数组的旋转版本。

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;

2
  • 计算最大公约数
  • 判断数字是否为回文数
  • 确定数字是否仅由...组成
  • 确定一个数字包含多少个...

1

这是一种简单的方法来判断一个数字是偶数还是奇数。只需进行 # mod 2 运算,如果结果是 0 则为偶数,1 则为奇数。


1

通常,在循环中,您希望在第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之间的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接