วิธีที่รวดเร็วในการนับบิตที่ไม่ใช่ศูนย์ในจำนวนเต็มบวก


117

ฉันต้องการวิธีที่รวดเร็วในการนับจำนวนบิตเป็นจำนวนเต็มใน python วิธีแก้ปัญหาปัจจุบันของฉันคือ

bin(n).count("1")

แต่ฉันสงสัยว่ามีวิธีไหนที่เร็วกว่านี้ไหม

PS: (ฉันเป็นตัวแทนของอาร์เรย์ไบนารี 2D ขนาดใหญ่เป็นรายการตัวเลขเดียวและทำการดำเนินการแบบบิตและนั่นทำให้เวลาลดลงจากชั่วโมงเป็นนาทีและตอนนี้ฉันต้องการกำจัดนาทีพิเศษเหล่านั้น

แก้ไข: 1. ต้องอยู่ใน python 2.7 หรือ 2.6

และการเพิ่มประสิทธิภาพสำหรับตัวเลขขนาดเล็กไม่ได้มีความสำคัญมากนักเนื่องจากนั่นจะไม่ใช่ปัญหาคอขวดที่ชัดเจน แต่ฉันมีตัวเลข 10,000 + บิตในบางที่

ตัวอย่างเช่นนี่เป็นกรณี 2,000 บิต:

12448057941136394342297748548545082997815840357634948550739612798732309975923280685245876950055614362283769710705811182976142803324242407017104841062064840113262840137625582646683068904149296501029754654149991842951570880471230098259905004533869130509989042199261339990315125973721454059973605358766253998615919997174542922163484086066438120268185904663422979603026066685824578356173882166747093246377302371176167843247359636030248569148734824287739046916641832890744168385253915508446422276378715722482359321205673933317512861336054835392844676749610712462818600179225635467147870208L

ที่เกี่ยวข้อง: stackoverflow.com/questions/407587/…
dusan

1
สิ่งที่ชนิดของการแสดงที่คุณใช้ถ้า "จำนวนเต็ม" ของคุณมีความยาวมากกว่างูหลามมาตรฐานint? ไม่มีวิธีการคำนวณของตัวเองหรือไม่?
Marcin

1
อาจซ้ำกันได้ของCount bits ของจำนวนเต็มใน Python
endolith

3
เพื่อแยกความแตกต่างของคำถามในstackoverflow.com/a/2654211/1959808 (ถ้าตั้งใจให้แตกต่างกัน --- อย่างน้อยก็ดูเหมือน) โปรดพิจารณาเปลี่ยนชื่อเป็น "... นับจำนวนที่ไม่ใช่ - ศูนย์บิต ... "หรือใกล้เคียงกัน มิฉะนั้นint.bit_lengthควรเป็นคำตอบไม่ใช่คำตอบที่ยอมรับด้านล่าง
Ioannis Filippidis

คำตอบ:


121

สำหรับจำนวนเต็มที่มีความยาวตามอำเภอใจbin(n).count("1")เป็นวิธีที่เร็วที่สุดที่ฉันพบใน Python บริสุทธิ์

ฉันลองปรับโซลูชันของÓscarและ Adam เพื่อประมวลผลจำนวนเต็มในส่วน 64 บิตและ 32 บิตตามลำดับ ทั้งสองอย่างช้ากว่าอย่างน้อยสิบเท่าbin(n).count("1")(รุ่น 32 บิตใช้เวลาประมาณครึ่งหนึ่งอีกครั้ง)

ในทางกลับกันgmpy popcount()ใช้เวลาประมาณ1/20ของเวลาของbin(n).count("1"). ดังนั้นหากคุณสามารถติดตั้ง gmpy ได้ให้ใช้สิ่งนั้น

ในการตอบคำถามในความคิดเห็นสำหรับไบต์ฉันใช้ตารางค้นหา คุณสามารถสร้างได้ที่รันไทม์:

counts = bytes(bin(x).count("1") for x in range(256))  # py2: use bytearray

หรือกำหนดตามตัวอักษร:

counts = (b'\x00\x01\x01\x02\x01\x02\x02\x03\x01\x02\x02\x03\x02\x03\x03\x04'
          b'\x01\x02\x02\x03\x02\x03\x03\x04\x02\x03\x03\x04\x03\x04\x04\x05'
          b'\x01\x02\x02\x03\x02\x03\x03\x04\x02\x03\x03\x04\x03\x04\x04\x05'
          b'\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06'
          b'\x01\x02\x02\x03\x02\x03\x03\x04\x02\x03\x03\x04\x03\x04\x04\x05'
          b'\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06'
          b'\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06'
          b'\x03\x04\x04\x05\x04\x05\x05\x06\x04\x05\x05\x06\x05\x06\x06\x07'
          b'\x01\x02\x02\x03\x02\x03\x03\x04\x02\x03\x03\x04\x03\x04\x04\x05'
          b'\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06'
          b'\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06'
          b'\x03\x04\x04\x05\x04\x05\x05\x06\x04\x05\x05\x06\x05\x06\x06\x07'
          b'\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06'
          b'\x03\x04\x04\x05\x04\x05\x05\x06\x04\x05\x05\x06\x05\x06\x06\x07'
          b'\x03\x04\x04\x05\x04\x05\x05\x06\x04\x05\x05\x06\x05\x06\x06\x07'
          b'\x04\x05\x05\x06\x05\x06\x06\x07\x05\x06\x06\x07\x06\x07\x07\x08')

จากนั้นก็counts[x]จะได้จำนวน 1 บิตxโดยที่ 0 ≤ x ≤ 255


7
+1! การสนทนานี้ไม่ถูกต้องอย่างไรก็ตามควรระบุไว้: bin(n).count("0")ไม่ถูกต้องเนื่องจากคำนำหน้า '0b' จะต้องมีbin(n)[2:].count('0')ไว้สำหรับผู้ที่นับไม่ได้ ....
หมาป่า

11
คุณไม่สามารถนับศูนย์บิตได้จริงๆโดยไม่รู้ว่าคุณกำลังเติมกี่ไบต์ซึ่งเป็นปัญหากับจำนวนเต็มแบบยาวของ Python เพราะอาจเป็นอะไรก็ได้
kindall

2
แม้ว่าสิ่งเหล่านี้จะเป็นตัวเลือกที่รวดเร็วสำหรับจำนวนเต็มเดียว แต่โปรดทราบว่าอัลกอริทึมที่นำเสนอในคำตอบอื่น ๆ อาจเป็นเวกเตอร์ได้ดังนั้นจึงเร็วกว่ามากหากทำงานในหลายองค์ประกอบของnumpyอาร์เรย์ขนาดใหญ่
gerrit

สำหรับอาร์เรย์ numpy ฉันจะตรวจสอบสิ่งนี้: gist.github.com/aldro61/f604a3fa79b3dec5436a
kindall

1
ฉันได้ใช้bin(n).count("1"). อย่างไรก็ตามมีเพียง 60% ของการส่ง python เท่านั้น @ leetcode
northtree

30

คุณสามารถปรับอัลกอริทึมต่อไปนี้:

def CountBits(n):
  n = (n & 0x5555555555555555) + ((n & 0xAAAAAAAAAAAAAAAA) >> 1)
  n = (n & 0x3333333333333333) + ((n & 0xCCCCCCCCCCCCCCCC) >> 2)
  n = (n & 0x0F0F0F0F0F0F0F0F) + ((n & 0xF0F0F0F0F0F0F0F0) >> 4)
  n = (n & 0x00FF00FF00FF00FF) + ((n & 0xFF00FF00FF00FF00) >> 8)
  n = (n & 0x0000FFFF0000FFFF) + ((n & 0xFFFF0000FFFF0000) >> 16)
  n = (n & 0x00000000FFFFFFFF) + ((n & 0xFFFFFFFF00000000) >> 32) # This last & isn't strictly necessary.
  return n

สิ่งนี้ใช้ได้กับตัวเลขบวก 64 บิต แต่สามารถขยายได้อย่างง่ายดายและจำนวนของการเติบโตของการดำเนินการด้วยลอการิทึมของอาร์กิวเมนต์ (กล่าวคือเป็นเชิงเส้นกับขนาดบิตของอาร์กิวเมนต์)

เพื่อให้เข้าใจวิธีการทำงานให้จินตนาการว่าคุณแบ่งสตริง 64 บิตทั้งหมดออกเป็น 64 บัคเก็ต 1 บิต ค่าของที่เก็บข้อมูลแต่ละรายการจะเท่ากับจำนวนบิตที่ตั้งไว้ในที่เก็บข้อมูล (0 หากไม่มีการตั้งค่าบิตและ 1 หากตั้งค่าหนึ่งบิต) การแปลงครั้งแรกส่งผลให้อยู่ในสถานะที่คล้ายคลึงกัน แต่มี 32 บัคเก็ตแต่ละอันยาว 2 บิต สิ่งนี้ทำได้โดยการเปลี่ยนที่เก็บข้อมูลอย่างเหมาะสมและเพิ่มค่าของพวกเขา (การเพิ่มหนึ่งครั้งจะดูแลที่เก็บข้อมูลทั้งหมดเนื่องจากไม่มีการพกพาในที่เก็บข้อมูล - จำนวนบิตจะยาวพอที่จะเข้ารหัสหมายเลข n เสมอ) การเปลี่ยนแปลงเพิ่มเติมนำไปสู่สถานะที่มีจำนวนที่เก็บข้อมูลที่มีขนาดเติบโตแบบทวีคูณลดลงอย่างมากจนกว่าเราจะมาถึงที่เก็บข้อมูลยาว 64 บิต สิ่งนี้จะให้จำนวนบิตที่ตั้งไว้ในอาร์กิวเมนต์ดั้งเดิม


ฉันไม่รู้อย่างจริงจังว่าสิ่งนี้จะทำงานกับตัวเลข 10,000 บิตได้อย่างไร แต่ฉันชอบวิธีแก้ปัญหา คุณช่วยบอกฉันหน่อยได้ไหมว่าฉันจะประยุกต์ใช้กับตัวเลขที่ใหญ่กว่านี้ได้อย่างไรและอย่างไร
zidarsk8

ฉันไม่เห็นจำนวนบิตที่คุณกำลังจัดการอยู่ที่นี่ คุณคิดจะเขียนโค้ดจัดการข้อมูลด้วยภาษาระดับต่ำเช่น C หรือไม่? อาจเป็นส่วนขยายของรหัส python ของคุณ? คุณสามารถปรับปรุงประสิทธิภาพได้อย่างแน่นอนโดยใช้อาร์เรย์ขนาดใหญ่ใน C เทียบกับตัวเลขขนาดใหญ่ใน python ที่กล่าวว่าคุณสามารถเขียนCountBits()เพื่อจัดการตัวเลข 10k-bits ได้โดยเพิ่มโค้ดเพียง 8 บรรทัด แต่มันจะเทอะทะเนื่องจากค่าคงที่มาก
Adam Zalcman

2
คุณสามารถเขียนโค้ดเพื่อสร้างลำดับของค่าคงที่และตั้งค่าลูปสำหรับการประมวลผล
Karl Knechtel

คำตอบนี้มีข้อดีอย่างมากที่สามารถทำเป็นเวกเตอร์สำหรับกรณีที่ต้องจัดการกับnumpyอาร์เรย์ขนาดใหญ่
gerrit

17

นี่คือการใช้ Python ของอัลกอริทึมการนับประชากรตามที่อธิบายไว้ในโพสต์นี้:

def numberOfSetBits(i):
    i = i - ((i >> 1) & 0x55555555)
    i = (i & 0x33333333) + ((i >> 2) & 0x33333333)
    return (((i + (i >> 4) & 0xF0F0F0F) * 0x1010101) & 0xffffffff) >> 24

0 <= i < 0x100000000มันจะทำงานให้


ที่ฉลาด มองสิ่งนี้แทนการยิงคำตอบจากสะโพกนั้นเหมาะสมอย่างยิ่ง!
MrGomez

1
คุณเปรียบเทียบสิ่งนี้หรือไม่? ในเครื่องของฉันโดยใช้ python 2.7 ฉันพบว่าสิ่งนี้ช้ากว่าbin(n).count("1")ไฟล์.
David Weldon

@DavidWeldon ไม่ฉันไม่ได้คุณช่วยโพสต์เกณฑ์มาตรฐานของคุณได้ไหม
ÓscarLópez

%timeit numberOfSetBits(23544235423): 1000000 loops, best of 3: 818 ns per loop; %timeit bitCountStr(23544235423): 1000000 loops, best of 3: 577 ns per loop.
gerrit

7
อย่างไรก็ตามnumberOfSetBitsประมวลผล 864 × 64 ของฉันnumpy.ndarrayใน 841 µs เนื่องจากbitCountStrฉันต้องวนซ้ำอย่างชัดเจนและใช้เวลานานกว่า 40.7 มิลลิวินาทีหรือนานกว่าเกือบ 50 เท่า
gerrit

8

ตามโพสต์นี้ดูเหมือนว่าจะเป็นการใช้น้ำหนัก Hamming ที่เร็วที่สุด(ถ้าคุณไม่สนใจที่จะใช้หน่วยความจำประมาณ 64KB)

#http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable
POPCOUNT_TABLE16 = [0] * 2**16
for index in range(len(POPCOUNT_TABLE16)):
    POPCOUNT_TABLE16[index] = (index & 1) + POPCOUNT_TABLE16[index >> 1]

def popcount32_table16(v):
    return (POPCOUNT_TABLE16[ v        & 0xffff] +
            POPCOUNT_TABLE16[(v >> 16) & 0xffff])

ใน Python 2.x คุณควรแทนที่rangeด้วยxrange.

แก้ไข

หากคุณต้องการประสิทธิภาพที่ดีขึ้น (และตัวเลขของคุณเป็นจำนวนเต็มมาก) ไปที่GMPไลบรารี ประกอบด้วยการใช้งานประกอบที่เขียนด้วยมือสำหรับสถาปัตยกรรมต่างๆมากมาย

gmpy เป็นโมดูลส่วนขยาย Python ที่ใช้รหัส C ที่ห่อหุ้มไลบรารี GMP

>>> import gmpy
>>> gmpy.popcount(2**1024-1)
1024

ฉันได้แก้ไขคำถามของฉันเพื่อให้ชัดเจนว่าฉันต้องการสิ่งนี้สำหรับตัวเลขขนาดใหญ่ (10k บิตขึ้นไป) การเพิ่มประสิทธิภาพบางอย่างสำหรับจำนวนเต็ม 32 บิตนั้นน่าจะไม่ทำให้เกิดความแตกต่างมากนักเนื่องจากจำนวนการนับจะต้องมีขนาดใหญ่มากซึ่งในกรณีนี้จะทำให้เวลาดำเนินการช้า
zidarsk8

แต่ GMP นั้นมีไว้สำหรับตัวเลขขนาดใหญ่มากรวมถึงตัวเลขที่เกินขนาดที่คุณกล่าวถึง
James Youngman

1
ใช้หน่วยความจำจะดีกว่าถ้าคุณใช้array.arrayสำหรับPOPCOUNT_TABLE16เป็นแล้วมันจะถูกเก็บไว้เป็นอาร์เรย์ของจำนวนเต็มแทนที่จะเป็นรายการขนาดแบบไดนามิกของงูใหญ่intวัตถุ
gsnedders

6

ฉันชอบวิธีนี้มาก มันง่ายและค่อนข้างเร็ว แต่ยังไม่ จำกัด ความยาวบิตเนื่องจาก python มีจำนวนเต็มไม่สิ้นสุด

จริงๆแล้วมันฉลาดกว่าที่คิดเพราะหลีกเลี่ยงการเสียเวลาในการสแกนเลขศูนย์ ตัวอย่างเช่นจะใช้เวลาเท่ากันในการนับบิตชุดใน 1000000000000000000000010100000001 เช่นเดียวกับ 1111

def get_bit_count(value):
   n = 0
   while value:
      n += 1
      value &= value-1
   return n

ดูดี แต่เหมาะสำหรับจำนวนเต็ม "กระจัดกระจาย" เท่านั้น โดยเฉลี่ยแล้วมันค่อนข้างช้า ถึงกระนั้นก็ดูมีประโยชน์มากในบางกรณีการใช้งาน
zidarsk8

ฉันไม่ค่อยแน่ใจว่าคุณหมายถึงอะไร "โดยเฉลี่ยแล้วมันค่อนข้างช้า" ค่อนข้างช้าเมื่อเทียบกับอะไร? คุณหมายถึงช้าเมื่อเทียบกับรหัส python อื่น ๆ ที่คุณไม่ได้อ้างถึงหรือไม่? เร็วเป็นสองเท่าของการนับทีละบิตสำหรับจำนวนเฉลี่ย ในความเป็นจริงบน macbook ของฉันมันนับได้ 12.6 ล้านบิตต่อวินาทีซึ่งเร็วกว่าที่ฉันนับได้มาก หากคุณมีอัลกอริทึม python ทั่วไปอื่นที่ใช้ได้กับความยาวของจำนวนเต็มและเร็วกว่านี้ฉันอยากจะได้ยินเกี่ยวกับเรื่องนี้
Robotbugs

1
ฉันยอมรับว่ามันช้ากว่าคำตอบของมานูเอลข้างต้นจริงๆ
Robotbugs

ค่อนข้างช้าโดยเฉลี่ยการนับบิตสำหรับ 10,000 ตัวเลขที่มี 10,000 หลักใช้เวลา 0.15 วินาทีbin(n).count("1")แต่ใช้เวลา 3.8 วินาทีสำหรับฟังก์ชันของคุณ หากตัวเลขมีจำนวนบิตน้อยมากมันจะทำงานได้เร็ว แต่ถ้าคุณใช้ตัวเลขสุ่มใด ๆ โดยเฉลี่ยแล้วฟังก์ชันข้างต้นจะเป็นคำสั่งของขนาดที่ช้าลง
zidarsk8

ตกลงฉันจะยอมรับสิ่งนั้น ฉันเดาว่าฉันเป็นแค่ดิ๊กเพราะคุณเป็นคนไม่ค่อยเข้าใจ แต่คุณพูดถูกทั้งหมด ฉันไม่ได้ทดสอบวิธีการโดยใช้วิธีการของ Manuel ด้านบนก่อนความคิดเห็นของฉัน มันดูเกะกะมาก แต่จริงๆแล้วมันเร็วมาก ตอนนี้ฉันใช้เวอร์ชันแบบนั้น แต่มี 16 ค่าในพจนานุกรมและเร็วกว่าที่เขายกมาเสียอีก แต่สำหรับเร็กคอร์ดนั้นฉันใช้ของฉันในแอปพลิเคชันที่มีเพียงไม่กี่บิตที่ตั้งค่าเป็น 1 แต่สำหรับบิตแบบสุ่มทั้งหมดใช่แล้วมันจะอยู่ที่ประมาณ 50:50 โดยมีความแปรปรวนเล็กน้อยลดลงตามความยาว
Robotbugs

3

คุณสามารถใช้อัลกอริทึมเพื่อรับสตริงไบนารี [1] ของจำนวนเต็ม แต่แทนที่จะเชื่อมสตริงเข้าด้วยกันให้นับจำนวนสตริง:

def count_ones(a):
    s = 0
    t = {'0':0, '1':1, '2':1, '3':2, '4':1, '5':2, '6':2, '7':3}
    for c in oct(a)[1:]:
        s += t[c]
    return s

[1] https://wiki.python.org/moin/BitManipulation


ทำงานได้รวดเร็ว มีข้อผิดพลาดอย่างน้อยใน p3 [1:] ควรเป็น [2:] เนื่องจาก oct () ส่งกลับ '0o' ก่อนสตริง รหัสจะทำงานเร็วขึ้นมากแม้ว่าคุณจะใช้ hex () แทน oct () และสร้างพจนานุกรม 16 รายการ
Robotbugs

2

คุณบอกว่า Numpy ช้าเกินไป คุณใช้มันเพื่อจัดเก็บแต่ละบิตหรือไม่? ทำไมไม่ขยายแนวคิดในการใช้ ints เป็นบิตอาเรย์ แต่ใช้ Numpy เพื่อจัดเก็บสิ่งเหล่านี้

จัดเก็บ n บิตเป็นอาร์เรย์ของ ceil(n/32.) ints 32 บิต จากนั้นคุณสามารถทำงานกับอาร์เรย์ numpy แบบเดียวกับที่คุณใช้ ints รวมถึงการใช้เพื่อทำดัชนีอาร์เรย์อื่น

โดยพื้นฐานแล้วอัลกอริทึมจะคำนวณจำนวนบิตที่กำหนดในแต่ละเซลล์แบบขนานและจะสรุปจำนวนบิตของแต่ละเซลล์

setup = """
import numpy as np
#Using Paolo Moretti's answer http://stackoverflow.com/a/9829855/2963903
POPCOUNT_TABLE16 = np.zeros(2**16, dtype=int) #has to be an array

for index in range(len(POPCOUNT_TABLE16)):
    POPCOUNT_TABLE16[index] = (index & 1) + POPCOUNT_TABLE16[index >> 1]

def popcount32_table16(v):
    return (POPCOUNT_TABLE16[ v        & 0xffff] +
            POPCOUNT_TABLE16[(v >> 16) & 0xffff])

def count1s(v):
    return popcount32_table16(v).sum()

v1 = np.arange(1000)*1234567                       #numpy array
v2 = sum(int(x)<<(32*i) for i, x in enumerate(v1)) #single int
"""
from timeit import timeit

timeit("count1s(v1)", setup=setup)        #49.55184188873349
timeit("bin(v2).count('1')", setup=setup) #225.1857464598633

แม้ว่าฉันจะแปลกใจที่ไม่มีใครแนะนำให้คุณเขียนโมดูล C



-2

ปรากฎว่าการเป็นตัวแทนเริ่มต้นของคุณคือรายการของรายการ ints ซึ่งเป็น 1 หรือ 0 เพียงแค่นับพวกมันในการแสดงนั้น


จำนวนบิตในจำนวนเต็มเป็นค่าคงที่ใน python

อย่างไรก็ตามหากคุณต้องการนับจำนวนบิตที่ตั้งไว้วิธีที่เร็วที่สุดคือการสร้างรายการที่สอดคล้องกับรหัสเทียมต่อไปนี้: [numberofsetbits(n) for n in range(MAXINT)]

สิ่งนี้จะช่วยให้คุณสามารถค้นหาเวลาได้อย่างต่อเนื่องหลังจากที่คุณสร้างรายการแล้ว ดูคำตอบของ @ PaoloMoretti สำหรับการใช้งานที่ดี แน่นอนคุณไม่จำเป็นต้องเก็บทั้งหมดนี้ไว้ในหน่วยความจำ - คุณสามารถใช้ที่เก็บคีย์ - ค่าถาวรบางประเภทหรือแม้แต่ MySql (อีกทางเลือกหนึ่งคือใช้ที่เก็บข้อมูลบนดิสก์แบบธรรมดาของคุณเอง)


@StevenRumbalski มันไม่มีประโยชน์ยังไง?
Marcin

เมื่อฉันอ่านคำตอบของคุณมันมีเพียงประโยคแรกของคุณ: "จำนวนบิตในจำนวนเต็มเป็นค่าคงที่ใน python"
Steven Rumbalski

ฉันมีตารางการค้นหาการนับจำนวนเล็กน้อยสำหรับการนับทั้งหมดที่สามารถจัดเก็บได้ แต่มีรายการตัวเลขจำนวนมากและดำเนินการกับ [i] & a [j] ทำให้การแก้ปัญหาของคุณไร้ประโยชน์เว้นแต่ฉันจะมี 10+ หน่วยความจำ GB อาร์เรย์สำหรับ & ^ | สำหรับสามเท่าของ 10,000 ตัวเลขจะเป็นขนาดตารางการค้นหา 3 * 10,000 ^ 3 เนื่องจากฉันไม่รู้ว่าฉันต้องการอะไรมันจึงสมเหตุสมผลกว่าที่จะนับสองสามพันเมื่อฉันต้องการ
zidarsk8

@ zidarsk8 หรือคุณสามารถใช้ฐานข้อมูลบางประเภทหรือที่เก็บคีย์ - ค่าถาวร
Marcin

@ zidarsk8 10 + GB ของ ram ไม่ใหญ่จนน่าตกใจ หากคุณต้องการคำนวณตัวเลขอย่างรวดเร็วการใช้เหล็กขนาดกลาง - ใหญ่ก็ไม่สมเหตุสมผล
Marcin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.