Thuật toán để kiểm tra xem danh sách các số nguyên có trùng với nhau không


8

Có bất kỳ thuật toán hiệu quả nào để kiểm tra xem danh sách các số nguyên có phải là cặp song song hay không, hoặc thuật toán tổng quát hơn có phải là lựa chọn tốt nhất không?


Để chắc chắn, bạn có nghĩa là mọi cặp số nguyên trong tập hợp của bạn là đồng thời?
Draconis

2
có, mọi sự kết hợp của 2 số nguyên phải là số nguyên
dùng2782067

Câu trả lời:


8

Đầu tiên, hai sự thật về số nguyên coprime:

  • Nếu b là nguyên tố cùng nhau thì a b = l c m ( a , b )abab=lcm(a,b)
  • Iff là coprime cho cả bc , sau đó a là coprime cho b cabcabc

Nó sau từ này là một tập hợp các số nguyên phân biệt {a,b,z} là nguyên tố cùng nhau từng đôi nếu sản phẩm của mình bằng bội số chung nhỏ nhất của nó.

Bạn có thể tính bội số chung nhỏ nhất bằng cách sử dụng danh tính sau:

tôicm(một,b,c)= =tôicm(một,tôicm(b,c))

Giả sử bạn có số có k chữ số, và nhân / chia / sửa hai số là O ( 1 ) (có thể là một giả định tốt tùy thuộc vào mô hình của bạn), sau đó:nkO(1)

  • Tính sản phẩm của tập hợp của bạn mất O(n)
  • Tính gcd của hai số lấy O(k)
  • Tính lcm của hai số do đó cũng mất , bằng cách giảm xuống gcdO(k)
  • Vì vậy, việc tính lcm của toàn bộ tập hợp của bạn mất O(nk)

Do đó, độ phức tạp thời gian của toàn bộ thuật toán là .O(nk)


2
Nếu OP thực sự đang thực hiện điều này, có thể đáng để đánh giá xem sản phẩm / lcm có bằng nhau cho mỗi số khi chúng được đọc chứ không phải sau khi nhân tất cả chúng / lcm-ing tất cả chúng. Điều này sẽ không thay đổi độ phức tạp nhưng nếu bạn cho rằng hầu hết các danh sách không phải là số nguyên tố (như trường hợp của một danh sách dài các số ngẫu nhiên) thì rất có thể sẽ nhanh hơn
sudo rm -rf chém

5
@DW Tôi tin rằng vấn đề là bằng cách kiểm tra tăng dần, bạn có thể bảo lãnh sớm một khi ví dụ không phải là nguyên nhân đầu tiên được tìm thấy, trái ngược với chỉ sau khi xử lý toàn bộ danh sách. Vì chúng tôi hy vọng hầu hết các danh sách sẽ không được ghép theo cặp và chúng tôi không có bất kỳ thông tin nào về danh sách đang được kiểm tra, nên chúng tôi hy vọng rằng danh sách đó có thể sẽ không được ghép theo cặp, và do đó tiến hành một quy trình được tối ưu hóa cho trường hợp phổ biến đó .
Andrea Reina

@AndreaReina chính xác cảm ơn vì đã viết nó rõ ràng hơn
sudo rm -rf chém

Một lưu ý thực hiện khác ... Sử dụng gcd == 1 thay vì lcm == prod có lẽ dễ dàng hơn vì theo như tôi biết thì thuật toán lcm tốt nhất vẫn sử dụng gcd
sudo rm -rf chém

2
Nếu bạn đếm số chữ số của các số, sẽ không có nghĩa khi giả định rằng phép nhân và phép chia là . Chúng Ω ( k a ) với một số k > 1 . O(1)Ω(ka)k>1
Gilles 'SO- ngừng trở nên xấu xa'

4

Đúng. Cách tiếp cận ngây thơ của việc kiểm tra từng cặp số cần thời gian bậc hai, nhưng có các thuật toán hiệu quả hơn. Có một thuật toán thời gian gần như tuyến tính, được mô tả trong bài báo sau:

Daniel J. Bernstein. Bao thanh toán vào các phần tử trong thời gian tuyến tính . Tạp chí thuật toán 54 (2005), 1--30.

Xem thêm https://cstheory.stackexchange.com/q/3393/5038 . Điều đó gần như hiệu quả như bạn có thể hy vọng.

Để làm rõ điều này giúp ích như thế nào với tình huống của bạn, một khi bạn đã tìm thấy một cơ sở đồng thời và xác định từng yếu tố trên cơ sở, việc kiểm tra xem chúng có phải là cặp song song hay không: nếu chúng không phải là cặp đôi, thì một số cặp sẽ có điểm chung yếu tố, và đó sẽ là một yếu tố nằm trong cơ sở đồng thời và có mặt trong yếu tố của cả hai. Nếu không có yếu tố nào phổ biến để trình bày trong hệ số của hai hoặc nhiều số, thì bạn biết các số đó là cặp số nguyên. Một khi bạn có các yếu tố, bạn có thể dễ dàng kiểm tra thời gian tuyến tính xem có bất kỳ số nào trong nhiều hơn một hệ số không.


2
Tôi không thấy làm thế nào Factoring over a coprime baseliên quan đến checking if a list of integers is pairwise coprime(chưa).
greybeard

@greybeard, xem câu trả lời được chỉnh sửa - Tôi đã thêm một đoạn ở cuối giải thích.
DW

2

Tìm các thừa số nguyên tố của mỗi số. Các số này đều là cặp số cộng nhau khi và chỉ khi mỗi số nguyên tố trong toàn bộ bộ sưu tập là khác biệt. Kiểm tra này có thể được thực hiện trong thời gian O (n) bằng cách sử dụng bảng băm.

Chỉnh sửa: Câu trả lời của Draconis là tốt hơn, bởi vì nó không yêu cầu bất kỳ yếu tố nào. Tính toán GCD nhanh hơn nếu số của bạn lớn và / hoặc số nguyên tố.


2
Bao thanh toán rất chậm. Theo như chúng tôi biết, không có thuật toán hiệu quả để bao thanh toán - và chúng tôi chắc chắn không biết về một thuật toán nào mất thời gian O (n). Về cơ bản, thuật toán này sẽ gần với thời gian theo cấp số nhân (về mặt kỹ thuật, thời gian phụ nhưng thời gian siêu đa thức).
DW
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.