แมปอาร์เรย์ 2D เข้ากับอาร์เรย์ 1D


94

ฉันต้องการแสดงอาร์เรย์ 2 มิติด้วยอาร์เรย์ 1D ฟังก์ชันจะส่งผ่านสองตัวบ่งชี้ (x, y) และค่าที่จะจัดเก็บ ตัวบ่งชี้ทั้งสองนี้จะแสดงถึงองค์ประกอบเดียวของอาร์เรย์ 1D และตั้งค่าตามนั้น ฉันรู้ว่าอาร์เรย์ 1D ต้องมีขนาดของ arrayWidth × arrayHeight แต่ฉันไม่รู้วิธีตั้งค่าแต่ละองค์ประกอบ

ตัวอย่างเช่นฉันจะแยกแยะ (2,4,3) จาก (4,2,3) ได้อย่างไร ฉันลองตั้งค่าอาร์เรย์เป็น x * y แต่ 2 * 4 และ 4 * 2 จะทำให้เกิดจุดเดียวกันในอาร์เรย์และฉันต้องการให้มันต่างกัน

คำตอบ:


168

คุณต้องตัดสินใจว่าจะจัดเก็บองค์ประกอบอาร์เรย์ตามลำดับแถวหรือลำดับคอลัมน์จากนั้นจึงสอดคล้องกัน http://en.wikipedia.org/wiki/Row-major_order

ภาษาซีใช้ลำดับแถวสำหรับอาร์เรย์หลายมิติ

ในการจำลองสิ่งนี้ด้วยอาร์เรย์มิติเดียวคุณคูณดัชนีแถวด้วยความกว้างและเพิ่มดัชนีคอลัมน์ดังนี้:


7
ผมคิดว่าคำตอบนี้ชัดเจนกว่าโดยเฉพาะผู้เริ่มต้นไม่ควรเขียนฟังก์ชันในบรรทัดเดียว ... !! เป็นการปฏิบัติที่ไม่ดีต่อไป .. :)
Lipis

3
คำตอบนี้ยังมีประโยชน์เมื่อคุณมีคอมไพเลอร์ (เช่นระบบฝังตัว) ที่ไม่มีการรองรับอาร์เรย์หลายมิติที่เหมาะสม
Alex Marshall

1
เป็นที่น่าอัศจรรย์ที่มีคนจำนวนมากที่สามารถตอบคำถามเดียวกันได้อย่างถูกต้อง แต่มีเพียงคนเดียวเท่านั้นที่ตอบคำถามนี้ด้วยวิธีที่เข้าใจง่าย นี่เป็นคำตอบง่ายๆที่ได้รับ อย่างไรก็ตามจอห์นเป็นเพียงคนเดียวที่ให้คำตอบที่ดีได้ ส่วนที่เหลือทั้งหมดเป็นถังขยะที่สามารถเข้าใจได้ง่ายโดยผู้ที่รู้คำตอบอยู่แล้ว ขอบคุณจอห์นที่พูดภาษาอังกฤษแทนคนต่างด้าว เพียงแค่แสดงให้เห็นว่าบางคนสอนแย่แค่ไหนและครูที่ดีอย่าง John Knoeller รู้วิธีทำให้ง่ายขึ้นและสื่อสารได้อย่างมีประสิทธิภาพมากกว่าคนอื่น ๆ
user2948630

6
มันจะดีจะแสดงวิธีการสลับการแมปนี้ถ้าดัชนีของอาร์เรย์ 1D เป็นalphaและอาร์เรย์ 2 มิติมีมิติNในทั้งสองทิศทางกับดัชนีx, yแล้วตาม alpha=x+N*y@JohnKnoeller, วิธีที่จะกลับนี้จะตั้งค่าและx=alpha%N y= (alpha-alpha%N)/N
ทิม

ฉันมาที่นี่เกือบทุกวัน!
Felipe Gutierrez

24

สูตรทั่วไปสำหรับการคำนวณดัชนีอาร์เรย์ 2 มิติใหม่เป็นดัชนีอาร์เรย์ 1D คือ

หรือคุณสามารถใช้

(สมมติว่าarrayWidthวัดตามแกน X และarrayHeightตามแกน Y)

แน่นอนเราสามารถสร้างสูตรต่างๆมากมายที่ให้การแมปเฉพาะทางเลือกอื่น ๆ แต่โดยปกติแล้วไม่จำเป็นต้องทำ

ในภาษา C / C ++ อาร์เรย์หลายมิติในตัวจะถูกเก็บไว้ในหน่วยความจำเพื่อให้ดัชนีสุดท้ายเปลี่ยนแปลงเร็วที่สุดซึ่งหมายความว่าสำหรับอาร์เรย์ที่ประกาศเป็น

องค์ประกอบxy[5][3]ตามมาทันทีxy[5][4]ในหน่วยความจำ คุณอาจต้องการทำตามแบบแผนนั้นเช่นกันโดยเลือกหนึ่งในสองสูตรข้างต้นขึ้นอยู่กับดัชนี (X หรือ Y) ที่คุณคิดว่าเป็น "สุดท้าย" ของทั้งสอง


17

ตัวอย่าง: เราต้องการแสดงอาร์เรย์ 2 มิติที่มีขนาด SIZE_X และ SIZE_Y นั่นหมายความว่าเราจะมีขนาด MAXX แถวต่อเนื่องกัน MAXY ดังนั้นฟังก์ชันเซ็ตคือ

สิ่งที่ได้รับคือ:


1
MAXXและMAXYค่าของคุณได้รับการตั้งชื่ออย่างสับสนเนื่องจากค่าสูงสุดของxและyเป็นMAXX - 1และMAXY - 1ตามลำดับ บางทีSIZE_XและSIZE_Yอาจจะดีกว่า
คาเฟ่

3
[y * maxx + x] คือลำดับคอลัมน์ไม่ใช่ลำดับแถว นี่เป็นวิธีการทำงานของ matlab แต่ไม่ใช่วิธีที่อาร์เรย์ปกติทำงานใน C.
John Knoeller

@ ทุกคน: เว้นแต่คุณจะเก็บข้อมูลไว้สัมผัส แต่ฟังก์ชั่นรับ / ตั้งค่าทั้งสองนี้อย่างหมดจดและใช้สูตรเดียวกันคุณสามารถทำเช่นนี้หรืออย่างนั้นได้ (รับประกัน!)
imacake

มาโครอาจเหมาะสมกว่าที่นี่ดังนั้นคุณจึงไม่ต้องซ้อนการเรียกฟังก์ชันที่ไม่จำเป็นในสิ่งที่ควรจะเป็นการเข้าถึงข้อมูลระดับต่ำ (โดยเฉพาะอย่างยิ่งเนื่องจากการจัดทำดัชนี 1d ในอาร์เรย์หลอก 2d บางครั้งก็เป็นเทคนิคการเพิ่มประสิทธิภาพ
krs013

สมมติว่ารหัสเป็นสมาชิกชั้นเรียนรหัสนี้จะได้รับการอินไลน์ อินไลน์มิฉะนั้นอย่างชัดเจนเป็นมากดีกว่าแมโคร
Kornel Kisielewicz

7

เช่นเดียวกับที่คนอื่น ๆ กล่าวว่าแผนที่ C ตามลำดับแถว

เอาท์พุต:


3

โดยใช้ตัวอย่างแถวหลัก:


1

สิ่งสำคัญคือต้องจัดเก็บข้อมูลในลักษณะที่สามารถเรียกดูได้ในภาษาที่ใช้ ร้านค้าภาษา C ตามลำดับแถวหลัก (แถวแรกทั้งหมดมาก่อนจากนั้นแถวที่สองทั้งหมด ... ) โดยทุกดัชนีจะทำงานตั้งแต่ 0 ถึงมิติที่ 1 ดังนั้นลำดับของอาร์เรย์ x [2] [3] คือ x [0] [0], x [0] [1], x [0] [2], x [1] [0], x [1] [ 1], x [1] [2] ดังนั้นในภาษา C x [i] [j] จะถูกเก็บไว้ที่เดียวกับรายการอาร์เรย์ 1 มิติ x1dim [i * 3 + j] หากข้อมูลถูกจัดเก็บด้วยวิธีนั้นการดึงข้อมูลในภาษาซีก็ทำได้ง่าย

Fortran และ MATLAB นั้นแตกต่างกัน พวกเขาจัดเก็บในลำดับคอลัมน์หลัก (คอลัมน์แรกทั้งหมดมาก่อนจากนั้นแถวที่สองทั้งหมด ... ดังนั้นลำดับดัชนีจึงเป็นสิ่งที่ตรงกันข้ามของ C และดัชนีทั้งหมดมีค่ามากกว่า 1 หากคุณจัดเก็บข้อมูลตามลำดับภาษา C FORTRAN จะค้นหา X_C_language [i] [j] โดยใช้ X_FORTRAN (j + 1, i + 1) ตัวอย่างเช่น X_C_language [1] [2] เท่ากับ X_FORTRAN (3,2) ในอาร์เรย์ 1 มิติค่าข้อมูลนั้นอยู่ที่ X1dim_C_language [2 * Cdim2 + 3] ซึ่งเป็นตำแหน่งเดียวกับ X1dim_FORTRAN (2 * Fdim1 + 3 + 1) โปรดจำไว้ว่า Cdim2 = Fdim1 เนื่องจากลำดับของดัชนีจะกลับรายการ

MATLAB เหมือนกับ FORTRAN Ada เหมือนกับ C ยกเว้นโดยปกติดัชนีจะเริ่มต้นที่ 1 ภาษาใด ๆ ก็ตามจะมีดัชนีอยู่ในคำสั่ง C หรือ FORTRAN อย่างใดอย่างหนึ่งและดัชนีจะเริ่มต้นที่ 0 หรือ 1 และสามารถปรับเปลี่ยนได้เพื่อให้ได้ข้อมูลที่จัดเก็บไว้

ขออภัยหากคำอธิบายนี้ทำให้สับสน แต่ฉันคิดว่ามันถูกต้องและสำคัญสำหรับโปรแกรมเมอร์ที่ต้องรู้


-2

คุณควรจะสามารถเข้าถึงอาร์เรย์ 2d โดยใช้ตัวชี้แบบธรรมดา อาร์เรย์ [x] [y] จะถูกจัดเรียงในตัวชี้เป็น p [0x * width + 0y] [0x * width + 1y] ... [0x * width + n-1y] [1x * width + 0y] ฯลฯ .

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