Що перше у двовимірному масиві, рядках чи стовпцях?


Відповіді:


90

Java вважається "основним рядком", це означає, що він робить рядки першими. Це пов’язано з тим, що 2D-масив є «масивом масивів».

Наприклад:

int[ ][ ] a = new int[2][4];  // Two rows and four columns.

a[0][0] a[0][1] a[0][2] a[0][3]

a[1][0] a[1][1] a[1][2] a[1][3]

Його також можна візуалізувати більш таким чином:

a[0] ->  [0] [1] [2] [3]
a[1] ->  [0] [1] [2] [3]

Друга ілюстрація демонструє аспект "масив масивів". Перший масив містить {a[0] and a[1]}, і кожен з них являє собою масив , що містить чотири елементи, {[0][1][2][3]}.

TL; Анотація DR:

Array[number of arrays][how many elements in each of those arrays]

Для отримання додаткових пояснень див. Також Масиви - 2-мірні .


8
Мені сподобалась візуалізація, наведена у цій відповіді.
Донато

1
Мене не переконують, що ця відповідь або вихідний матеріал переконливо демонструють, що рядки повинні бути першим числом. Я не бачу причини, щоб ми не могли спочатку робити стовпці, а потім рядки. І якщо це конвенція, я не бачу тут нічого, що чітко це підтверджує.
Матьє К.

1
OP не запитував причину "чому" Java є основною (що технічно не є, але найлегше її осмислити, якщо ви уявляєте, що вона є, і менше турбуєтесь про розміщення пам'яті). Але радше запитували "як хто пам'ятає", щоб спочатку концептуально вказати рядки. Я вважаю візуалізацію найкращим способом запам'ятати. Слід зазначити , що Java не реально використовувати ряд основних самі по собі, але на самому справі визначає масиви, через масивів , як я торкаюся на короткий час в моїй обороні. Дійсно хороша візуалізація пояснення того , як його викладений можна знайти тут: stackoverflow.com/a/6631081/1366973
MrHappyAsthma

21

Незважаючи на те, що Matt B's може бути правдою в одному сенсі, це може допомогти думати про багатовимірний масив Java, не думаючи про геометричні матриці взагалі. Яскраві масиви Java - це просто масиви масивів, і кожен елемент першого "виміру" може мати різний розмір від інших елементів, або фактично може зберігати нульовий "під" масив. Див. Коментарі до цього питання


5
+1 за вираження контрасту ARRAY проти MATRIX! Масиви не мають геометричного визначення. Якщо ви думаєте, що 1D-масив вертикальний, тоді рядок - перший, якщо ви думаєте, що 1D-масив горизонтальний, тоді col - перший. При використанні прямокутного 2D-масиву не існує логічної різниці, якщо ви залишаєте його однаковим у всьому коді. ВПРОВАДЖЕННЯ ВІД ВАШОГО ВИКОРИСТАННЯ! (не змушуйте себе обходити перший елемент кожного підмасиву, коли ви можете просто пройти перший підмасив)
Рон

15

Інстинктивно мислиться геометрично: горизонтальна (X) вісь, а потім вертикальна (Y) вісь. Однак це не стосується двовимірного масиву, спочатку рядки, а потім стовпці.

Розглянемо таку аналогію: в геометрії підходить до сходів (вісь X) і піднімається по ній (вісь Y). І навпаки, в Java людина спускається по сходах (ряди) і відходить (стовпці).


11
@Luiggi Будь ласка, зверніться до " Це нормально запитувати і відповідати на власне запитання, в якому ви знайдете (серед іншого):To be crystal clear, it is not merely OK to ask and answer your own question, it is explicitly encouraged.
Matt B

1
Це стосується таких питань, як це чи це гарне запитання . Крім того, переконайтеся, що обидва питання - це спільнота wiki (голосування не додає репутації цим людям), вони мають гарне пояснення і зроблені для того, щоб допомогти людям, а не отримати користь для себе.
Луїджі Мендоса,

@ Zéychin Це, мабуть, було б доречнішим у чаті.
Matt B

Добре уявити собі транспонування. тобто, якщо ви уявляєте, що стовпці стоять першими, то рядки - це справді нормально. і це часто зустрічається в алгоритмах матричних операцій, написаних на Java.
Мохамед Ель-Накіб,

На жаль, стандарту не існує. Коли люди говорять про екрани комп’ютерів, вони кажуть «ширина за висотою», наприклад, 1024x768 або 1440x900. Але коли люди говорять про картки рецептів, вони кажуть: "картка 3х5".
Dave Burton

5

Все залежить від вашої візуалізації масиву. Рядки та стовпці - це властивості візуалізації (можливо, у вашій уяві) масиву, а не самого масиву.

Це точно те саме, що запитати число "5" червоне чи зелене?

Я міг намалювати його червоним, я міг намалювати це жадібність, так? Колір не є невід'ємною властивістю числа. Таким же чином представлення 2D-масиву як сітки рядків і стовпців не є необхідним для існування цього масиву.

2D-масив має лише перший і другий розміри , все, що стосується їх візуалізації, - це виключно ваш смак.

Коли у мене є масив char char[80][25], я можу хотіти надрукувати його на повороті консолі, щоб у мене було 25 рядків із 80 символів, які відповідають екрану без прокрутки.

Я спробую навести життєздатний приклад, коли представляти 2D-масив як рядки та стовпці взагалі не має сенсу : Скажімо, мені потрібен масив з 1 000 000 000 цілих чисел. На моїй машині є 8 ГБ оперативної пам’яті, тому у мене для цього достатньо пам’яті, але якщо ви спробуєте виконати var a = new int[1000000000], швидше за все, ви отримаєте виняток OutOfMemory. Це через фрагментацію пам’яті - послідовного блоку пам’яті такого розміру не існує. Натомість ви можете створити 2D-масив 10 000 x 100 000 зі своїми значеннями. Логічно, що це 1D масив, тому ви хотіли б намалювати і уявити його як єдину послідовність значень, але завдяки технічній реалізації це 2D.


Цікавий момент! Я ніколи не думав про те, як масив масивів використовуватиме фрагментацію пам'яті. Для подальшого руху додому, перше число буде представляти кількість покажчиків, а друге число - довжину масиву, на який вказує кожен покажчик (що також означає, що 2D-версія 1D-масиву фактично виділяє БІЛЬШЕ пам'яті заради ці вказівники).
4скасл

@ 4castle, ти маєш рацію, зубчастий масив буде використовувати трохи більше пам'яті, ніж еквівалентний 2D-масив фіксованого розміру, але іноді це може напрочуд врятувати вас від винятку OutOfMemory. Я думаю, це через те, що .NET намагається розподілити великі об'єкти за допомогою послідовних блоків пам'яті (не впевнений, чому відображення блоків віртуальної пам'яті не вирішує проблему). Хоча я не фахівець у моделі пам’яті .NET, тому не сприймайте це як факт.
Саша

.NET? Це було питання Java. Чи використовує Windows JVM .NET?
4скасл,

@ 4castle, Вибачте, я вже забув, що це питання Java, але я майже впевнений, що в .NET та JVM немає великих відмінностей з точки зору представлення нерівних та простих одновимірних масивів у пам'яті.
Саша

2

У Java немає багатовимірних масивів. Є масиви масивів. Так:

int[][] array = new int[2][3];

Насправді він складається з двох масивів, кожен з яких має три елементи.


1
"... кожен має 3 масиви." ви мали на увазі "кожен має по 3 елементи ". ?
Мухаммед Гелбана,

1
Я не впевнений, що це відповідає на поставлене запитання. При оголошенні масивів масивів, рядки спочатку чи стовпці спочатку?
Матьє К.

1

Найкращий спосіб запам'ятати, якщо рядки чи стовпці стоять першими, - це написати коментар та згадати його.

Java не зберігає 2D-масив як таблицю із зазначеними рядками та стовпцями, він зберігає його як масив масивів, як пояснюється у багатьох інших відповідях. Тож ви можете вирішити, перший чи другий вимір - це ваш рядок. Вам просто потрібно прочитати масив залежно від цього.

Отож, оскільки мене це постійно бентежить, я завжди пишу коментар, який говорить мені, який розмір 2-го масиву є моїм рядком, а який - моїм стовпцем.


0

У Java рядки виконуються спочатку, оскільки двовимірний масив вважається двома окремими масивами. Починається з першого рядка 1 розмірний масив.


1
Це в C #, а не в Java. У мові програмування Java багатовимірний масив - це масив, компоненти якого самі є масивами. Отже, кожен масив компонентів може мати різну довжину. Цей запис, який ви пишете, знаходиться на мові C #, який змушує прямокутний 2D-масив - якого у Java немає - що еквівалентно примушуванню всіх масивів компонентів мати однакову довжину.
Мохамед Ель-Накіб

Дякую :) Мухаммад Аннакіб
Нур Лабабіді

Дякую, я не знав частини про прямокутну частину 2D-масиву. Це корисна відповідь.
Nour Lababidi

Я оновив свою відповідь до більш детальної та правильної відповіді. Дякую,
Нур Лабабіді,

0

У c ++ (віддалена, запилена пам'ять) я думаю, було трохи легше дивитись на код і розуміти масиви, ніж це іноді на Java. Обидва вони є основними. Ця ілюстрація допомогла мені зрозуміти.

Враховуючи цей код для 2d масиву рядків ...

    String[][] messages; 
    messages = new String[][] {
        {"CAT","DOG","YIN","BLACK","HIGH","DAY"},
        {"kitten","puppy","yang","white","low","night"} 
    };
    
    int row = messages.length;
    int col = messages[0].length;
    

Іменуючи мої ints так, ніби це 2d-масив (рядок, col), ми бачимо значення.

row = (int) 2
col = (int) 6

Останні два рядки коду, де ми намагаємось визначити розмір і встановити для них row і colне виглядає все так інтуїтивно і це не обов'язково правильно.

Тут ви справді маєте справу з цим (зверніть увагу на нові назви змінних для ілюстрації):

int numOfArraysIn = messages.length;
int numOfElementsIn0 = messages[0].length;
int numOfElementsIn1 = messages[1].length;

Де messages.lengthтобі підказуєmessages є два масиви. Масив масивів.

І тоді messages[x].lengthотримує розмір кожного з окремих масивів 0 1усередині messages.

numOfArraysIn = (int) 2
numOfElementsIn0 = (int) 6
numOfElementsIn1 = (int) 6

Коли ми друкуємо з для кожного циклу ....

for (String str : messages[0])
        System.out.print(str);
for (String str : messages[1])
        System.out.print(str);

CATDOGYINBLACKHIGHDAYkittenpuppyyangwhitelownight

Спроба скинути дужки та друкувати таким чином видає помилку

for (String str : messages)
        System.out.print(str);

incompatible types: String[] cannot be converted to String

Вищесказане важливо розуміти під час налаштування циклів, які використовують .lengthдля обмеження кроку через масив.


0

У клітинках TStringGrid властивість Col стоїть на першому місці.

Property Cells[ACol, ARow: Integer]: string read GetCells write SetCells;

Тож присвоєння StringGrid1.cells[2, 1] := 'abcde';значення відображається у третьому стовпці другого рядка.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.