2010-04-09 5 views
45

Tôi biết toán tử modulus (%) tính phần còn lại của một bộ phận. Làm thế nào tôi có thể xác định một tình huống mà tôi sẽ cần phải sử dụng các nhà điều hành modulus?Nhận biết khi nào nên sử dụng toán tử mô đun

Tôi biết tôi có thể sử dụng toán tử mô đun để xem liệu số đó là số chẵn hay lẻ hay số nguyên tố, nhưng đó là về nó. Tôi không thường nghĩ về số dư. Tôi chắc rằng toán tử modulus rất hữu dụng và tôi muốn học cách tận dụng nó.

Tôi chỉ gặp sự cố khi xác định nơi áp dụng toán tử mô đun. Trong các tình huống lập trình khác nhau, rất khó cho tôi để xem một vấn đề và nhận ra "Này! Phần còn lại của bộ phận sẽ làm việc ở đây!".

+0

Về cơ bản, nó được sử dụng cho thời gian, ngày tháng và lặp lại chuỗi – Donato

Trả lời

4

Ví dụ. Bạn có tin nhắn của X byte, nhưng trong kích thước tối đa của giao thức của bạn là Y và Y < X. Hãy thử viết ứng dụng nhỏ tách thông báo thành các gói và bạn sẽ chạy vào mod :)

2

Có nhiều trường hợp hữu ích .

Nếu bạn cần hạn chế số nằm trong một phạm vi nhất định, bạn có thể sử dụng mod. Ví dụ, để tạo ra một số ngẫu nhiên giữa 0 và 99 bạn có thể nói:

num = MyRandFunction() % 100; 
+6

-1. Điều này sẽ tạo ra các kết quả không thống nhất trừ khi 100 là một ước số của phạm vi 'MyRandFunction()'. (Hãy tưởng tượng bạn muốn một số ngẫu nhiên trong '0 .. RAND_MAX * 2/3'.) – kennytm

+1

@KennyTM: +1. Điều có lẽ sẽ tốt hơn là có thể vượt qua 100 _into_ MyRandFunction(), điều này sẽ giải quyết nó đúng cách. Thêm vào đó cung cấp đóng gói tốt hơn, và nhiều khớp nối lỏng lẻo hơn. – Cam

+0

Được bỏ phiếu cho một trường hợp sử dụng phổ biến khác. (câu hỏi không phải là về việc tạo ra âm thanh crypto psrn) – danecando

3

Tính toán số nguyên tố

+7

Mặc dù tôi đã không thực sự tìm thấy một tình huống mà tôi thực sự cần thiết để tính toán chúng. – anonymous

+0

Thuật toán trao đổi khóa Diffie-Hellman, mã hóa pgp –

23

Hãy tưởng tượng rằng bạn có một thời gian trôi qua trong vài giây và bạn muốn chuyển đổi này để giờ, phút và giây:

h = s/3600; 
m = (s/60) % 60; 
s = s % 60; 
10

tôi đã sử dụng nó khi hạn chế một số thành một nhiều chắc chắn:

temp = x - (x % 10); //Restrict x to being a multiple of 10 
+0

Bạn có thể sử dụng thực tế điều này không? –

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

Bạn có thấy nó đã làm gì không? Ở bước cuối cùng nó quay trở lại số không. Điều này có thể được sử dụng trong các tình huống như:

  1. Để kiểm tra xem N chia hết cho M (ví dụ, lẻ hoặc chẵn) hoặc N là một bội số của M.

  2. Để đặt một nắp của một giá trị cụ thể. Trong trường hợp này 3.

  3. Để lấy các chữ số M cuối cùng của một số -> N% (10^M).
+0

Bạn có thể giải thích tình huống số 3 không? Để lấy các chữ số M cuối cùng của một số -> N% (10^M). –

+0

Ví dụ: trong [sô-cô-la lịch mùa vọng] (https://en.wikipedia.org/wiki/Advent_calendar) để chia cho 3 người. Anna mở cửa lịch/cửa sổ vào ngày đầu tiên (1) và ăn sô cô la, Ben vào ngày thứ 2 và Carl vào ngày thứ 3, sau đó lại là Anna, v.v. Thực hiện 'ngày% 3' và khi kết quả là 1: Anna, 2: Ben, 0: Carl. Mọi người đều có sô cô la của họ mà không tính toán lớn. – JonyD

10
  • Giá trị gói (như đồng hồ).
  • Cung cấp các trường hữu hạn cho các thuật toán khóa đối xứng.
  • Hoạt động bitwise.

Và cứ tiếp tục như vậy.

3

Bất cứ khi nào bạn có bộ phận và muốn thể hiện phần còn lại khác với số thập phân, toán tử mod thích hợp. Những điều bạn nghĩ đến thường là khi bạn muốn làm điều gì đó mà con người có thể đọc được với phần còn lại. Liệt kê có bao nhiêu mục bạn có thể đặt vào nhóm và nói "5 còn lại" là tốt.

Ngoài ra, nếu bạn đang ở trong tình huống mà bạn có thể tích lũy lỗi làm tròn, việc chia nhỏ modulo là tốt.Ví dụ: nếu bạn chia cho 3 thường xuyên, bạn không muốn chuyển qua .33333 xung quanh thành phần còn lại. Việc chuyển phần còn lại và số chia (tức là phân số) là thích hợp.

2

Mô-đun cũng rất hữu ích nếu vì lý do điên rồ nào đó bạn cần chia số nguyên và nhận số thập phân, và bạn không thể chuyển đổi số nguyên thành số hỗ trợ phân số thập phân hoặc nếu bạn cần trả về phân số thay vì một số thập phân.

tôi sẽ sử dụng % như các nhà điều hành mô đun

Ví dụ

2/4 = 0

nơi làm điều này

2/4 = 0 and 2 % 4 = 2

Vì vậy, bạn có thể thực sự điên rồ và giả sử mà bạn muốn cho phép người dùng nhập một tử số và một số chia, và sau đó hiển thị cho họ kết quả dưới dạng số nguyên và sau đó là số phân số.

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

Một trường hợp phân chia mô đun rất hữu ích là nếu bạn đang tăng hoặc giảm một số và bạn muốn chứa số lượng đến một phạm vi nhất định của số lượng, nhưng khi bạn nhận được để phía trên hoặc phía dưới bạn không muốn dừng lại. Bạn muốn lặp lại đến cuối hoặc đầu danh sách tương ứng.

Hãy tưởng tượng một hàm mà bạn đang lặp qua một mảng.

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

Lý do là n = (n + biến)% (listString.maxIndex + 1) là cho phép chỉ số tối đa được tính.

Đó chỉ là một vài trong số những điều mà tôi đã phải sử dụng modulus trong chương trình của tôi không chỉ các ứng dụng máy tính để bàn, mà còn trong môi trường mô phỏng và robot.

16

Tôi sử dụng nó cho thanh tiến trình và tương tự đánh dấu tiến độ thông qua một vòng lặp lớn. Tiến trình chỉ được báo cáo mỗi lần thứ n thông qua vòng lặp hoặc khi đếm% n == 0.

+0

Bạn cũng thế? Nó thực sự tạo ra sự khác biệt lớn về tốc độ. – Kawa

+2

Nó thực sự. Đối với một phiên bản nhanh hơn, tôi thích sử dụng bit logic: 'count & 0xff == 0' (bạn có thể sử dụng 0xf hoặc 0xff hoặc 0xfff hoặc như vậy: điểm là có một số trong nhị phân là một chuỗi rắn 1s) – Tobia

3

Như @jweyrich nói, đóng gói giá trị. Tôi đã tìm thấy mod rất tiện dụng khi tôi có danh sách hữu hạn và tôi muốn lặp lại nó trong vòng lặp - như danh sách màu cố định cho một số yếu tố giao diện người dùng, như chuỗi biểu đồ, nơi tôi muốn tất cả các chuỗi khác nhau, mức độ có thể, nhưng khi tôi đã hết màu, chỉ để bắt đầu lại từ đầu. Điều này cũng có thể được sử dụng với, ví dụ, các mẫu, do đó, lần thứ hai màu đỏ xuất hiện xung quanh, nó bị gạch ngang; lần thứ ba, rải rác, vv - nhưng mod chỉ được sử dụng để có được màu đỏ, xanh lá cây, xanh dương, đỏ, xanh lá cây, xanh dương, mãi mãi.

2
  • Đang tính toán ước chung lớn nhất
  • Xác định nếu một số là một palindrome
  • Xác định nếu một số bao gồm chỉ ...
  • Xác định có bao nhiêu ... một số bao gồm ...
3

Các modulo có thể hữu ích để chuyển đổi và chia tổng số phút để "giờ và phút":

giờ = phút/60

MINUTES_LEFT = phút% 60

Trong những giờ chút chúng tôi cần phải tách phần thập phân và điều đó sẽ phụ thuộc vào ngôn ngữ bạn đang sử dụng.

Sau đó, chúng tôi có thể sắp xếp lại kết quả cho phù hợp.

+0

Chúng tôi cũng có thể sử dụng mô đun để tìm xem liệu một năm có phải là năm nhuận hay không vì nó có thể chia hết cho 4. Ví dụ trong JS: if (year% 4 === 0) {// đó là năm nhuận}. (Lưu ý: kiểm tra chính xác hơn cũng sẽ xác minh tính chia hết cho 100 và 400) – tony

4

Chuyển đổi cấu trúc dữ liệu tuyến tính để ma trận cấu trúc: nơi a là chỉ số của dữ liệu tuyến tính, và b là số hạng mục cho mỗi hàng:

row = a/b 
column = a mod b 

Note trên được đơn giản hóa logic: a phải được bù đắp -1 trước chia & kết quả phải được chuẩn hóa +1.

Ví dụ: (3 hàng 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 

Một sử dụng phổ biến của mô đun: băm một số bởi nơi. Giả sử bạn muốn lưu trữ năm & tháng trong một số có sáu chữ số 195810. month = 195810 mod 100 tất cả các chữ số thứ 3 từ phải chia hết cho 100, còn lại là 2 chữ số ngoài cùng bên phải trong trường hợp này là tháng 10. Để trích xuất năm 195810/100 sản lượng 1958.

+0

Tại sao bạn phải bù đắp bằng 1? –

1

Sử dụng yêu thích của tôi là để lặp lại.

Giả sử bạn có bộ đếm bạn đang tăng và muốn lấy từ danh sách đã biết, một mục tương ứng, nhưng bạn chỉ có n mục để chọn và bạn muốn lặp lại một chu kỳ.

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

Kết quả (counter=indexFromB) cho n=3:

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

Một trường hợp sử dụng tôi thấy thời gian gần đây là khi bạn cần phải đảo ngược một số. Vì vậy, ví dụ: 123456 trở thành 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; 
} 
1

Đây là một cách dễ dàng để biết số có đồng đều hay lẻ không. Chỉ cần làm # mod 2, nếu nó là 0 nó là ngay cả, 1 nó là lẻ.