Tìm Số Nguyên Tố Trong Lập Trình Bằng Cách Nào? – cách xác định số nguyên tố

Với những bạn học CNTT thì số nguyên tố là một thử thách khổ cực với đồng loạt các bài toán lập trình, hãy cùng khám phá kỹ về nó nhé

Bạn đang xem: cách xác định số nguyên tố

Chắc các bạn còn nhớ đến năm trước hết của cấp 2, một trong số các bài học “vỡ lòng” của môn số học là `Số nguyên tố` – các con số `cô quạnh` khi to hơn 1 & chỉ chia hết cho 1 & chính nó.
Với các bạn không học sâu về toán thì số nguyên tố chỉ đang là một định nghĩa, với những bạn học chuyên toán thì số nguyên tố sẽ đi kèm với một loạt các thử thách trong bộ môn đại số & giải tích. Với những bạn học CNTT thì số nguyên tố là một thử thách khổ cực với đồng loạt các bài toán lập trình

Số nguyên tố là gì?

Nếu hỏi chị google “Định nghĩa số nguyên tố”, câu giải đáp tất cả chúng ta thu được sẽ là: “-Theo wikipedia-, số nguyên tố là số tự nhiên lớn hơn 1 không phải là tích của hai số tự nhiên nhỏ hơn. Số tự nhiên lớn hơn 1 không phải là số nguyên tố được gọi là hợp số. Chẳng hạn, 5 là số nguyên tố bởi vì cách duy nhất để viết nó dưới dạng một tích, 1 × 5 hoặc 5 × 1, có một thừa số là chính số 5….”

Cách xác định một số nguyên tố với dân lập trình:

Theo như định nghĩa ở trên, cách dễ dàng nhất để xác định number có phải là số nguyên tố không là tạo thành một vòng lặp từ 2 đến number - 1, nếu number chia hết cho một số nào đó thì number là một hợp số.

Code dễ dàng được viết bằng python:

def

is_prime_basic

(

number

):

if

number

<

2

:

return

False

for

value

in

range

(

2

,

number

):

if

number

%

value

==

:

return

False

return

True

Kiểm soát thử

import

timeit

list_number

=

[

164650

,

39371

,

339779

,

909961

,

120017

,

33901

,

50377

,

563684

,

61280

,

375698

]

total_time

=

for

number

in

list_number

:

start

=

timeit

.

default_timer

()

result

=

is_prime_basic

(

number

)

stop

=

timeit

.

default_timer

()

result

=

is_prime_basic

(

number

)

print

(

"{} is a prime number: {}."

.

format

(

number

,

result

))

total_time

+=

stop

-

start

print

(

"Elapsed time: {}(second)"

.

format

(

total_time

))

Kết quả in ra màn hình

164650 is α prime number: False.
39371 is α prime number: True.
339779 is α prime number: False.
909961 is α prime number: False.
120017 is α prime number: True.
33901 is α prime number: False.
50377 is α prime number: True.
563684 is α prime number: False.
61280 is α prime number: False.
375698 is α prime number: False.
Elapsed time: 0.029753100000107224(second)

Thực tiễn thì tất cả chúng ta không cần thực hiện vòng lặp từ 2 –> number - 1 vì nếu number = α * ɓ với α <= ɓ thì chắc rằng α <= sqrt(number)

Chẳng hạn:

number = 36
 = 1 * 36
 = 2 * 18
 = 3 * 12
 = 4 * 9
 = 6 * 6

 sqrt(36) = 6

number = α * ɓ & 1 <= α <= 6

number = 48
 = 1 * 48
 = 2 * 24
 = 3 * 16
 = 4 * 12
 = 6 * 8

 sqrt(48) = 6.928203230275509

number = α * ɓ & 1 <= α <= 6,9 ~ < 7

Như thế tất cả chúng ta chỉ cần thực hiện vòng lặp từ 2 đến sqrt(number) + 1 là đã có thể kiểm soát được number có phải là số nguyên tố hay không.

import

math

def

is_prime_sqrt

(

number

):

if

number

<

2

:

return

False

max_range

=

int

(

math

.

sqrt

(

number

))

+

1

for

value

in

range

(

2

,

max_range

):

if

number

%

value

==

:

return

False

return

True

Chạy thử:

import

timeit

list_number

=

[

164650

,

39371

,

339779

,

909961

,

120017

,

33901

,

50377

,

563684

,

61280

,

375698

]

total_time

=

for

number

in

list_number

:

start

=

timeit

.

default_timer

()

result

=

is_prime_sqrt

(

number

)

stop

=

timeit

.

default_timer

()

print

(

"{} is a prime number: {}."

.

format

(

number

,

result

))

total_time

+=

stop

-

start

print

(

"Elapsed time: {}(second)"

.

format

(

total_time

))
164650 is α prime number: False.
39371 is α prime number: True.
339779 is α prime number: False.
909961 is α prime number: False.
120017 is α prime number: True.
33901 is α prime number: False.
50377 is α prime number: True.
563684 is α prime number: False.
61280 is α prime number: False.
375698 is α prime number: False.
Elapsed time: 0.00014700000019729487(second)

Với lần tối ưu vừa rồi đã giảm được kha khá thời gian thực hiện của function kiểm soát số nguyên tố. Nhưng tất cả chúng ta vẫn có thể ứng dụng một số tri thức toán học để thực hiện tối ưu tiếp bài toán này.

Xem Thêm  Thuộc tính chiều rộng tối thiểu CSS - chiều rộng tối thiểu tính bằng css

“Số 2 là số nguyên tố chẵn duy nhất” –> Dựa trên cảnh báo này, tất cả chúng ta có thể triển khai tiếp 2 hành động

  • Nếu

     

    number

     

    cần test là số chẵn thì chắc rằng

     

    number

     

    không phải số nguyên tố

  • Nếu

     

    number

     

    là số lẻ thì thay vì mang vòng lặp băt đầu từ 2 & bước nhảy 1 nhà cung cấp thì tất cả chúng ta sẽ mang vào vòng lặp bắt nguồn từ 3 & bước nhảy 2 nhà cung cấp.

import math

def is_prime_jump_2(number):
    if number == 2:
        return True
    if number % 2 == 0 or number < 2: 
        return False
    
    max_range = int(math.sqrt(number)) + 1
    for value in range(3, max_range, 2):
        if number % value == 0:
            return False
    return True

Chạy thử với bộ check

list_number = [164650, 39371, 339779, 909961, 120017 , 33901, 50377 , 563684, 61280, 375698]
total_time = 0
for number in list_number:
    start = timeit.default_timer()
    result = is_prime_jump_2(number)
    stop = timeit.default_timer()
    print("{} is a prime number: {}.".format(number, result))
    total_time +=  stop - start

print("Elapsed time: {}(second)".format(total_time))
164650 is α prime number: False.
39371 is α prime number: True.
339779 is α prime number: False.
909961 is α prime number: False.
120017 is α prime number: True.
33901 is α prime number: False.
50377 is α prime number: True.
563684 is α prime number: False.
61280 is α prime number: False.
375698 is α prime number: False.
Elapsed time: 9.88000001598266e-05(second)

Con số của lần này cũng rất ấn tượng, giảm thêm đối với lần trước kha hơi nhiều

Tiếp tục tối ưu bí quyết tìm kiếm số nguyên tố, tất cả chúng ta có thể xem qua đến phép sàng Eratosthenes (Sieve of Eratosthenes) . Cách thực hiện thuật toán này được miêu tả tường minh bằng hình ảnh chẳng hạn sau: (nguồn ảnh wikipedia.org)

Hình minh họa cho thấy thuật toán đơn giản để tìm số nguyên tố & các bội số

Các số tô màu giống nhau là cùng một họ mà dẫn đầu (đậm hơn) sẽ là số nguyên tố

Ứng dụng vào bài toán của các bạn, loại trừ các số nguyên tố nhỏ đặc biệt là 2, 3, 5; tất cả chúng ta sẽ dùng triệu chứng chia hết cho 2, 3, 5 để loại bỏ bớt các hợp số.

def is_prime_optimal(number):
    if number in [2, 3, 5]:
        return True
    if number % 2 == 0 or number % 3 == 0 or number % 5 == 0 or number < 2: 
        return False

    max_range = int(math.sqrt(number)) + 1
    for value in range(3, max_range, 2):
        if number % value == 0:
            return False
    return True

Nếu liệt kê các số từ 1 đến 48, với 3 số nguyên tố trước hết là 2, 3, 5; bỏ qua các số chia hết cho 2, 3, 5 (đặt vào dấu ()); tất cả chúng ta đã được các số như sau:

2 3 (4) 5 (6) 7 (8) (9) (10) 11 (12) 13 (14) (15) (16) 17 (18) 19 (20) (21) (22) 23 (24) (25) (26) (27) (28) 29 (30) 31 (32) (33) (34) (35) (36) 37 (38) (39) (40) 41 (42) 43 (44) (45) (46) 47 (48)

Nhìn vào danh mục số phía trên, các số không có trong dấu () là: 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47. & đây cũng là các số nguyên tố. Dựa trên lập luận này, tất cả chúng ta có thể tôn tạo thêm thành function bên dưới.

def is_prime_optimal(number):
    if number in [2, 3, 5]:
        return True
    if number % 2 == 0 or number % 3 == 0 or number % 5 == 0 or number < 2: 
        return False
    if number < 49:
        return True


    max_range = int(math.sqrt(number)) + 1
    for value in range(50, max_range, 2):
        if number % value == 0:
            return False
    return True

Tiếp tục thực hiện “gấp thếp” các số nguyên tố mới tìm được ở bên trên 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47 theo bí quyết sàng Eratosthenes, tất cả chúng ta tiếp tục loại bỏ được các số hợp số.

def is_prime_optimal(number):
    if number in [2, 3, 5]:
        return True
    if number % 2 == 0 or number % 3 == 0 or number % 5 == 0 or number < 2: 
        return False
    if number < 49:
        return True

    if (number %  7) == 0 or (number % 11) == 0 or (number % 13) == 0 or (number % 17) == 0 or 
       (number % 19) == 0 or (number % 23) == 0 or (number % 29) == 0 or (number % 31) == 0 or 
       (number % 37) == 0 or (number % 41) == 0 or (number % 43) == 0 or (number % 47) == 0:
        return False


    max_range = int(math.sqrt(number)) + 1
    for value in range(50, max_range, 2):
        if number % value == 0:
            return False
    return True

Đơn giản để nhận ra số nguyên tố kế đến ngay sau 47 là số 53; Thử thực hiện một phép lặp chầm chậm 49 đến bé hơn 53^2 = 2809, lọc bỏ các hợp số đáp ứng điều kiện chia hết cho 2, 3, 5 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47; tất cả chúng ta sẽ nhận được dãy số.

list_number = []
# 53 * 53 = 2809
for number in range(49, 2809):
    if number % 2 == 0 or number % 3 == 0 or number % 5 == 0 or 
    (number %  7) == 0 or (number % 11) == 0 or (number % 13) == 0 or (number % 17) == 0 or 
       (number % 19) == 0 or (number % 23) == 0 or (number % 29) == 0 or (number % 31) == 0 or 
       (number % 37) == 0 or (number % 41) == 0 or (number % 43) == 0 or (number % 47) == 0:
        continue
    print(number, sep=" ", end=" ")
    list_number.append(number)

Ta nhận được 1 dãy số

53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997 1009 1013 1019 1021 1031 1033 1039 1049 1051 1061 1063 1069 1087 1091 1093 1097 1103 1109 1117 1123 1129 1151 1153 1163 1171 1181 1187 1193 1201 1213 1217 1223 1229 1231 1237 1249 1259 1277 1279 1283 1289 1291 1297 1301 1303 1307 1319 1321 1327 1361 1367 1373 1381 1399 1409 1423 1427 1429 1433 1439 1447 1451 1453 1459 1471 1481 1483 1487 1489 1493 1499 1511 1523 1531 1543 1549 1553 1559 1567 1571 1579 1583 1597 1601 1607 1609 1613 1619 1621 1627 1637 1657 1663 1667 1669 1693 1697 1699 1709 1721 1723 1733 1741 1747 1753 1759 1777 1783 1787 1789 1801 1811 1823 1831 1847 1861 1867 1871 1873 1877 1879 1889 1901 1907 1913 1931 1933 1949 1951 1973 1979 1987 1993 1997 1999 2003 2011 2017 2027 2029 2039 2053 2063 2069 2081 2083 2087 2089 2099 2111 2113 2129 2131 2137 2141 2143 2153 2161 2179 2203 2207 2213 2221 2237 2239 2243 2251 2267 2269 2273 2281 2287 2293 2297 2309 2311 2333 2339 2341 2347 2351 2357 2371 2377 2381 2383 2389 2393 2399 2411 2417 2423 2437 2441 2447 2459 2467 2473 2477 2503 2521 2531 2539 2543 2549 2551 2557 2579 2591 2593 2609 2617 2621 2633 2647 2657 2659 2663 2671 2677 2683 2687 2689 2693 2699 2707 2711 2713 2719 2729 2731 2741 2749 2753 2767 2777 2789 2791 2797 2801 2803 

Thực hiện kiểm soát dãy số trên là hợp số hay số nguyên tố.

lst_not_prime = []
for number in list_number:
    if not is_prime_sqrt(number):
        print("{} is not a prime".format(number))
        lst_not_prime.append(number)

print("not a prime: {}".format(lst_not_prime))

Kết quả nhận được khá ấn tượng

not α prime: []

Có nghĩa là toàn bộ các số ở dãy số trên đều là số nguyên tố. Bổ sung thêm điều thú vị trên vào function is_prime_optimal:

def is_prime_optimal(number):
    if number in [2, 3, 5]:
        return True
    if number % 2 == 0 or number % 3 == 0 or number % 5 == 0 or number < 2: 
        return False
    if number < 49:
        return True
    if (number %  7) == 0 or (number % 11) == 0 or (number % 13) == 0 or (number % 17) == 0 or 
       (number % 19) == 0 or (number % 23) == 0 or (number % 29) == 0 or (number % 31) == 0 or 
       (number % 37) == 0 or (number % 41) == 0 or (number % 43) == 0 or (number % 47) == 0:
        return False
    if number < 2809:
        return True


    max_range = int(math.sqrt(number)) + 1
    for value in range(53, max_range, 2):
        if number % value == 0:
            return False
    return True

Chạy thử với bộ dữ liệu check cho các function bên trên, tất cả chúng ta nhận được kết quả:

164650 is α prime number: False.
39371 is α prime number: True.
339779 is α prime number: False.
909961 is α prime number: False.
120017 is α prime number: True.
33901 is α prime number: False.
50377 is α prime number: True.
563684 is α prime number: False.
61280 is α prime number: False.
375698 is α prime number: False.
Elapsed time: 5.829999918205431e-05(second)

Tính đến đây, tất cả chúng ta đã có một function kiểm soát số nguyên tố khá là hài lòng, tất cả chúng ta sẽ thực hiện chạy một tập số để kiểm soát performance của các function phía trên.

Chẳng hạn: thực hiện sinh đột nhiên một danh mục chứa 10 số nguyên, thực hiện kiểm soát các số trong danh mục có phải là số nguyên tố không & tổng hợp phép kiểm soát từng số cũng như tổng thời gian thực hiện kiểm soát 10 số trên.

Sau thời điểm chạy script dưới đây, tất cả chúng ta nhận được kết quả (kết quả này biến đổi khi chạy các scrip, tùy vào vào vận tốc giải quyết của dòng sản phẩm tính):

import math
import timeit
import random


def is_prime_basic(number):
    if number < 2:
        return False
    for value in range(2, number):
        if number % value == 0:
            return False
    return True


def is_prime_sqrt(number):
    if number < 2:
        return False
    max_range = int(math.sqrt(number)) + 1
    for value in range(2, max_range):
        if number % value == 0:
            return False
    return True


def is_prime_optimal(number):
    if number in [2, 3, 5]:
        return True
    if number % 2 == 0 or number % 3 == 0 or number % 5 == 0 or number < 2: 
        return False
    if number < 49:
        return True
    if (number %  7) == 0 or (number % 11) == 0 or (number % 13) == 0 or (number % 17) == 0 or 
       (number % 19) == 0 or (number % 23) == 0 or (number % 29) == 0 or (number % 31) == 0 or 
       (number % 37) == 0 or (number % 41) == 0 or (number % 43) == 0 or (number % 47) == 0:
        return False
    
    if number < 2809:
        return True
    
    max_range = int(math.sqrt(number)) + 1
    for value in range(53, max_range, 2):
        if number % value == 0:
            return False
    return True


def random_all_array(length):
    arr = []
    for index in range(length):
        arr.append(random.randint(1, 10**8))
    return arr


def run_basic_function(number):
    start = timeit.default_timer()
    result = is_prime_basic(number)
    stop = timeit.default_timer()
    print("Basic-function {0}: {1}: {2}(second)".format(number, result, (stop - start)))
    return stop - start


def run_sqrt_function(number):
    start = timeit.default_timer()
    result = is_prime_sqrt(number)
    stop = timeit.default_timer()
    print("Sqrt-function {0}: {1}: {2}(second)".format(number, result, (stop - start)))
    return stop - start    


def run_optimal_function(number):
    start = timeit.default_timer()
    result = is_prime_optimal(number)
    stop = timeit.default_timer()
    print("Optimal-function {0}: {1}: {2}(second)".format(number, result, (stop - start)))
    return stop - start 
    
def compare_performance():
    list_number = random_all_array(10)
    print(list_number)
    basic_time = 0
    sqrt_time = 0
    optimal_time = 0
    for number in list_number:
        basic_time += run_basic_function(number)
        sqrt_time += run_sqrt_function(number)
        optimal_time += run_optimal_function(number)
    print("Total elapsed time for `is_prime_basic` function   ", basic_time)
    print("Total elapsed time for `is_prime_sqrt` function    ", sqrt_time)
    print("Total elapsed time for `is_prime_optimal` function ", optimal_time)




# call to function
compare_performance()





[80909548, 64284912, 32561271, 59635875, 43704113, 42511163, 7564624, 62719360, 29119365, 49141585]
Basic-function 80909548: False: 3.000000106112566e-06(second)
Sqrt-function 80909548: False: 6.799999937356915e-06(second)
Optimal-function 80909548: False: 2.4000000848900527e-06(second)
Basic-function 64284912: False: 3.89999991057266e-06(second)
Sqrt-function 64284912: False: 5.599999894911889e-06(second)
Optimal-function 64284912: False: 1.3999999737279722e-06(second)
Basic-function 32561271: False: 2.699999868127634e-06(second)
Sqrt-function 32561271: False: 3.6999999792897142e-06(second)
Optimal-function 32561271: False: 1.2999998943996616e-06(second)
Basic-function 59635875: False: 2.4000000848900527e-06(second)
Sqrt-function 59635875: False: 3.2000000373955118e-06(second)
Optimal-function 59635875: False: 1.0999999631167157e-06(second)
Basic-function 43704113: True: 4.237569500000063(second)
Sqrt-function 43704113: True: 0.00046080000015535916(second)
Optimal-function 43704113: True: 0.0002480000000559812(second)
Basic-function 42511163: True: 4.04824050000002(second)
Sqrt-function 42511163: True: 0.0004547000000911794(second)
Optimal-function 42511163: True: 0.00024399999983870657(second)
Basic-function 7564624: False: 1.2000000424450263e-06(second)
Sqrt-function 7564624: False: 1.2999998943996616e-06(second)
Optimal-function 7564624: False: 6.000000212225132e-07(second)
Basic-function 62719360: False: 9.99999883788405e-07(second)
Sqrt-function 62719360: False: 1.300000121773337e-06(second)
Optimal-function 62719360: False: 4.999999418942025e-07(second)
Basic-function 29119365: False: 9.000000318337698e-07(second)
Sqrt-function 29119365: False: 1.199999815071351e-06(second)
Optimal-function 29119365: False: 4.999999418942025e-07(second)
Basic-function 49141585: False: 1.0999999631167157e-06(second)
Sqrt-function 49141585: False: 1.2999998943996616e-06(second)
Optimal-function 49141585: False: 6.000000212225132e-07(second)
Total elapsed time for `is_prime_basic` function    8.285826199999974
Total elapsed time for `is_prime_sqrt` function     0.0009398999998211366
Total elapsed time for `is_prime_optimal` function  0.0005003999997370556

Với kết quả như trên, tất cả chúng ta tuyệt đối có thể tín nhiệm vào vận tốc giải quyết của function 

is_prime_optimal

.

Tạm kết

Ngoài cách ứng dụng phép sàng Eratosthenes để tối ưu bài toán tìm số nguyên tố, tất cả chúng ta còn tồn tại thể tìm hiểu thêm các giải thuật khác như Lucas Pseudoprimes, Baillie and Wagstaff, Miller-Rabin,…


Đọc thêm những nội dung liên quan đến đề tài cách xác định số nguyên tố

LẬP TRÌNH PASCAL: SỐ NGUYÊN TỐ @365dha

  • Author: 365dha
  • Ngày đăng: 2020-11-12
  • Nhận xét: 4 ⭐ ( 2479 lượt nhận xét )
  • Khớp với kết quả tìm kiếm: Cụ thể Video ở phần phản hồi phía dưới.
    Các bạn nhấn LIKE & SHARE ủng hộ nhé! Đăng ký kênh Free tại: https://bit.ly/2Y4jlFZ
    365dha lập_trình_pascal số_nguyên_tố

Cách bấm laptop số phức trên CASIO 580 VNX

  • Author: toanthaydinh.com
  • Nhận xét: 5 ⭐ ( 1280 lượt nhận xét )
  • Khớp với kết quả tìm kiếm: Cách bấm laptop số phức. Cách giải phương trình số phức bằng máy tính Casio 580 VNX, Casio 580 Việt Nam + Plus & các máy tương đương khác.

Đặc tính & một số nguyên nhân dẫn theo trái luật của người chưa thành niên

  • Author: www.lapphap.vn
  • Nhận xét: 4 ⭐ ( 3373 lượt nhận xét )
  • Khớp với kết quả tìm kiếm:

Cách tra cứu số định danh cá nhân mau chóng nhất

  • Author: luatvietnam.vn
  • Nhận xét: 5 ⭐ ( 8071 lượt nhận xét )
  • Khớp với kết quả tìm kiếm: Nội dung này sẽ giải thích rõ ràng và cụ thể số định danh cá nhân là gì & chỉ dẫn cách tra cứu số định danh cá nhân một cách mau chóng nhất.

Cung Mọc là gì & cách xác định cung Mọc của các bạn

  • Author: bloganchoi.com
  • Nhận xét: 3 ⭐ ( 6032 lượt nhận xét )
  • Khớp với kết quả tìm kiếm: Cung Mọc là một định nghĩa thông dụng trong chiêm tinh học, cùng với cung Mặt Trời & cung Mặt Trăng tạo ra BIG3 trong bản đồ sao cá nhân của mỗi người. …

Quy định cách ly tận nhà với F0, F1 Covid-19 tiên tiến nhất

  • Author: vnexpress.net
  • Nhận xét: 3 ⭐ ( 1274 lượt nhận xét )
  • Khớp với kết quả tìm kiếm: F0 dừng cách ly sau 10 ngày xét nghiệm 2 lần âm tính, F1 đã tiêm đủ 2 mũi vaccine được tái hòa nhập sau 7 ngày nhưng đều cần tiếp tục theo dõi sức khỏe. – VnExpress

Giải toán online | Đại số, lượng giác, giải tích, xác suất, hóa học…

  • Author: bietmaytinh.com
  • Nhận xét: 5 ⭐ ( 1785 lượt nhận xét )
  • Khớp với kết quả tìm kiếm: Cung cụ trực tuyến giúp bạn giải toán qua mạng mau chóng. Nó có thể giải các dạng toán lớp 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12. Phụ trợ tiếng Việt.

Đọc thêm các nội dung khác thuộc chuyên đề: Kiến thức lập trình

Xem Thêm  7 Ví dụ về SQL JOIN với giải thích chi tiết - sql tham gia với các ví dụ

Viết một bình luận