JavaRush /Java Blogu /Random-AZ /Çoxölçülü massivlər

Çoxölçülü massivlər

Qrupda dərc edilmişdir
Çoxölçülü massivlər - 1

Birölçülü Java massivi nədir?

Massiv eyni tipli, primitiv və ya istinad elementlərinin sıralanmış çoxluğudur. Massivlər (əsasən bir ölçülü) haqqında ümumi məlumatı “ Java-da massivlər ” məqaləsində və JavaRush kursunda tapa bilərsiniz . Bu yazıda elementləri başqa massivlər olan massivlərdən danışacağıq. Belə massivlər çoxölçülü adlanır. Elementləri başqa massivlər, yəni massivlər massivi olan massiv ikiölçülü adlanır. Bütün dillərdə bu şəkildə qurulmuş çoxölçülü massivlər yoxdur, lakin Java-da belədir.

Java Çoxölçülü Massivlər, Ümumi Sintaksis

Ümumiyyətlə, Java-da çoxölçülü massivlər belə görünür:
Data_type[dimension1][dimension2][]..[dimensionN] array_name = new data_type[size1][size2].[sizeN];
Data_typeMassivdəki elementlərin növü haradadır . Primitiv və ya istinad (sinif) ola bilər. İçəridə olan mötərizə cütlərinin sayı dimensionmassivin ölçüsüdür (bizim vəziyyətimizdə - N). array_name— massiv adı size1...sizN— massivin hər ölçüsündə elementlərin sayı. Çoxölçülü massivlərin elan edilməsi:
int[][] twoDimArray; //two-dimensional array
String[][][] threeDimArray; //three-dimensional array
double[][][][][] fiveDimArray; // five-dimensional array
Bəlkə də bütün bunlar çox mücərrəd görünür, buna görə də indi çoxölçülü massivlərin konkret təzahürlərinə keçək - iki ölçülü və üç ölçülü. Fakt budur ki, Java tərtibatçıları bəzən iki ölçülü massivlərdən daha az istifadə edirlər - üçölçülü olanlar və hətta daha böyük massivlər olduqca nadirdir. Onlarla qarşılaşmamaq ehtimalınız yüksəkdir.

JavaRush kursunda çoxölçülü massivlər

JavaRush-da “adi” massivlər Java Sintaksis axtarışının 7-ci səviyyəsində işə salınır və daha sonra kursda onlara bir dəfədən çox rast gəlinir. Bəzən kurs boyu siz ikiölçülü massivlərlə (və ya onların köməyi ilə həll oluna bilən) problemlərlə rastlaşırsınız. İkiölçülü massivlər “ JavaRush-da oyunlar ” xüsusi bölməsinin oyun mühərrikində də istifadə olunur. Hələ orada olmamısınızsa, baxın və bir-iki oyun yaradın. Şərtlər və şərtlər ətraflı təlimatlarla birlikdə verilir və proqramlaşdırma bacarıqları üzrə mükəmməl təlim verəcəkdir. Üç ölçülü serialı Space Invaders oyununda tapmaq olar . Onun vasitəsilə animasiya üçün çərçivələr dəsti müəyyən edilir (və bu kadrların hər biri iki ölçülü massivdir). Əgər JavaSyntax axtarışını artıq başa vurmusunuzsa və ya sadəcə Java proqramlaşdırmasında əminsinizsə, bu klassik oyunun öz versiyasını yazmağa çalışın.

İki ölçülü Java massivi nədir?

Java-da ikiölçülü massiv massivlər massividir, yəni hər bir xana massiləyə istinad ehtiva edir. Lakin onu verilmiş sıra (birinci ölçü) və sütun sayı (ikinci ölçü) olan cədvəl şəklində təqdim etmək daha asandır. Bütün sətirlərin bərabər sayda elementə malik olduğu ikiölçülü massiv düzbucaqlı adlanır.

İki ölçülü massivlərin elan edilməsi, yaradılması və işə salınması

İki ölçülü massivin elan edilməsi və yaradılması proseduru birölçülü massivlə demək olar ki, eynidir:
int[][] twoDimArray = new int[3][4];
Bu massivdə 3 sətir və 4 sütun var. Düzbucaqlı ikiölçülü massivin ölçüsü (onlar düzbucaqlı olmaya bilər, daha çox aşağıda göstərilə bilər), yəni elementlərin ümumi sayı satırların sayını sütunların sayına vurmaqla müəyyən edilə bilər. İndi standart dəyərlərlə işə salınıb (doldurulur). Yəni sıfırlar. Onu bizə lazım olan dəyərlərlə dolduraq.
twoDimArray[0][0] = 5;//write the value 5 into the cell at the intersection of the zero row and zero column
twoDimArray[0][1] = 7; //write the value 7 into the cell at the intersection of the zero row and the first column
twoDimArray[0][2]  = 3;
twoDimArray[0][3] = 17;
twoDimArray[1][0] = 7;
twoDimArray[1][1] = 0;
twoDimArray[1][2] = 1;
twoDimArray[1][3] = 12;
twoDimArray[2][0] = 8;
twoDimArray[2][1] = 1;
twoDimArray[2][2] = 2;
twoDimArray[2][3] = 3;
Birölçülü massivlərdə olduğu kimi, başlatma prosedurunu daha sürətli yerinə yetirə bilərsiniz:
int [][] twoDimArray = {{5,7,3,17}, {7,0,1,12}, {8,1,2,3}};
Hər iki halda biz tam ədədlərlə doldurulmuş üç cərgə və dörd sütundan ibarət ikiölçülü massiv alacağıq. Многомерные массивы - 2

Ekranda ikiölçülü massivin göstərilməsi

Bu əməliyyatı yerinə yetirməyin ən məntiqli yolu əvvəlcə sıfır sətir elementini element üzrə, sonra ikincini və s. Java-da ikiölçülü massiv çıxarmağın ən ümumi yolu iki iç-içə döngədən istifadə etməkdir.
int [][] twoDimArray = {{5,7,3,17}, {7,0,1,12}, {8,1,2,3}};//declared an array and filled it with elements
for (int i = 0; i < 3; i++) {  //go through the lines
            for (int j = 0; j < 4; j++) {//go through the columns
                System.out.print(" " + twoDimArray[i][j] + " "); //output element
            }
            System.out.println();// line wrap for the visual preservation of the tabular form
        }

İki ölçülü massivin sürətli çıxışı

İkiölçülü massivin elementlərinin siyahısını ekranda göstərməyin ən qısa yolu deepToStringsinif metodundan istifadə etməkdir Arrays. Misal:
int[][] myArray = {{18,28,18},{28,45,90},{45,3,14}};
System.out.printLn(Arrays.deepToString(myArray));
Proqramın nəticəsi aşağıdakı çıxışdır: [[18, 28, 18], [28, 45, 90], [45, 3, 14]]

İki ölçülü massivin “uzunluqları”

Birölçülü massivin uzunluğunu (yəni onun içindəki elementlərin sayını) almaq üçün dəyişəndən istifadə edə bilərsiniz length. Yəni bir massivi təyin etsək int a[] = {1,2,3}, əməliyyat a.length3-ü qaytarır. Bəs eyni proseduru ikiölçülü massivimizə tətbiq etsək necə olar?
int [][] twoDimArray = {{5,7,3,17}, {7,0,1,12}, {8,1,2,3}};
System.out.println(twoDimArray.length);
Çıxış: 3 Beləliklə, bu əməliyyat massivdəki sıraların sayını çıxarır. Sütunların sayını necə əldə etmək olar? Əgər biz düzbucaqlı ikiölçülü massivlərlə (yəni bütün xətlərin eyni uzunluqda olduğu massivlərlə) məşğul oluruqsa, onda biz əməliyyatı twoDimArray[0].lengthvə ya sıfır elementin (əsasən sıfır xətti) yerinə - hər hansı digər mövcud olanı tətbiq edə bilərik. Biz bunu edə bilərik, çünki Java-da ikiölçülü massiv massivlər massividir, sıfır elementi isə twoDimArray[0]4 uzunluqlu massivdir. Bunu özünüz yoxlaya bilərsiniz.

İki ölçülü massivdən istifadə nümunəsi: dama taxtası

İki ölçülü massivlər hər hansı sonlu iki ölçülü sahə yaratmaq üçün istifadə edilə bilər, məsələn oyunlarda və xüsusən də şahmatda. Şahmat taxtasını iki ölçülü massiv kimi düşünmək asandır. Siz buna qrafikləri “əlavə edə” bilərsiniz, lakin hələlik simvollardan istifadə edərək şahmat taxtasını təyin edək və onu konsola çıxaraq. Многомерные массивы - 3Şahmat taxtasının aşağı sol kvadratı qara rəngə boyanıb, növbətisi yuxarıdakı kimi ağ rəngdədir. Beləliklə, hər dəfə yan tərəfə bitişik hücrəyə keçdiyiniz zaman rəng dəyişir. Şahmat rəngini əl ilə deyil, bir alqoritmdən istifadə edərək təyin etmək üçün paritet yoxlamasından istifadə edə bilərsiniz: əgər satır və sütun indeksinin cəmi cüt və ya sıfırdırsa, hüceyrə ağ olacaq, əks halda qara olacaq. Bu yoxlama üçün alqoritmdə qalan % operatorundan istifadə edirik. Qrafiklərlə deyil, simvollarla işlədiyimiz üçün ağ xananı hərflə W(ağ), qara xananı isə hərflə B(qara) işarələyəcəyik.
//set the chessboard as a two-dimensional array
String [][] chessBoard = new String[8][8];
        for (int i = 0; i< chessBoard.length; i++) {
            for (int j = 0; j < chessBoard[0].length; j++) {
                if ((i + j) % 2 == 0) chessBoard[i][j] = "W";
                else chessBoard[i][j] = "B";
            }
        }
Proqramın çıxışı belədir: WBWBWBWBBWBWBWBWWBWBW BWBBWBWBWBWWBWBWBWBBW BWBWBWWBWBWBWBBWBWBWB W Hər şey əsl şahmat taxtasındakı kimidir, onu yoxlaya bilərsiniz. Многомерные массивы - 4İndi xanaların düzgün nömrələnməsi üsulunu massiv dilində deyil, “şahmat” dilində yazaq. Lövhənin aşağı sol xanası A1 adlanır, bizim massivimizdə isə chessBoard[7][0]. Gəlin ikiölçülü massivin hər bir cüt indeksini onların “şahmat” ekvivalenti ilə əlaqələndirək. Bunu etmək üçün iki sətirdən istifadə edirik - " abcdefgh" və " 87654321" (əks qaydada - sadəlik üçün, dama taxtası 8 sıfır sütununa uyğundur).
public static String chessBoardCoord(int a, int b) {
            String letters = "abcdefgh";
            String numbers = "87654321";
            if ((a > 7)|| (b>7)) return null; //if the number is outside the board, return the default value - null
            else return (Character.toString(letters.charAt(a)) + numbers.charAt(b)); /*charAt - a method with which we extract from the string the element under the passed number, here - under the numbers a and b. Character.toString - a method that converts the received character into a string */
        }
İndi metoddan istifadə edərək hər bir xanada təkcə onun rəngini deyil, həm də nömrəsini göstərəkchessBoardCoord
String [][] chessBoard = new String[8][8];
        for (int i = 0; i < chessBoard.length; i++) {
            for (int j = 0; j < chessBoard[0].length; j++) {
                if ((i + j) % 2 == 0) chessBoard[i][j] = "W" + chessBoardCoord(j,i);
                else chessBoard[i][j] = "B"+ chessBoardCoord(j,i);
            }
        }

            for (int i = 0; i < chessBoard.length; i++) {
                for (int j = 0; j < chessBoard[0].length; j++) {
                    System.out.print(" " + chessBoard[i][j] + " ");
                }
                System.out.println();
            }
Proqram çıxışı: Wa8 Bb8 Wc8 Bd8 We8 Bf8 Wg8 Bh8 Ba7 Wb7 Bc7 Wd7 Be7 Wf7 Bg7 Wh7 Wa6 Bb6 Wc6 Bd6 We6 Bf6 Wg6 Bh6 Ba5 Wb5 Bc5 Wd5 Be5 Wf5 Bg5 Wh5 Wa4 Bb4 Wb4 Wh5 Wa4 Bb4 Wb4 B3 3 Be3 Wf3 Bg3 Wh3 Wa2 Bb2 Wc2 Bd2 We2 Bf2 Wg2 Bh2 Ba1 Wb1 Bc1 Wd1 Be1 Wf1 Bg1 Wh1 Burada We2e2 nömrəli ağ kvadrat nəzərdə tutulur.

İki ölçülü massivdən istifadə nümunəsi: matrisin vurulması

Diqqət!Bu nümunə matrislər haqqında əsas bilik tələb edir. Burada onlar haqqında çox az danışılacaq və bu məlumat matris arifmetikasını öyrənmiş, lakin bir qədər unudulmuşlar üçün nəzərdə tutulub. Bununla belə, bu məlumatı açıq mənbələrdən, xüsusən də Vikipediyadakı məqalədən əldə etmək olar . Bu, iki ölçülü massivlərdən istifadənin yaxşı nümunəsidir, lakin biz onsuz da davam edə bilərik. Beləliklə, riyazi baxımdan indi sizin üçün anlaşılmaz görünürsə və həqiqətən də onu araşdırmaq istəmirsinizsə, nümunədən qaçın. Əgər siz əsas xətti cəbri öyrənmisinizsə, düzbucaqlı massivləri düzbucaqlı matrislər kimi öyrənmiş ola bilərsiniz. Многомерные массивы - 5Burada a11, a12... aNN bəzi ədədlərdir. Şəkildə matris hətta düzbucaqlı deyil, kvadratdır (sətirlərin sayı sütunların sayına bərabərdir, lakin bu həmişə belə deyil). Real həyatda belə matrislərə nadir hallarda rast gəlinir, lakin proqramlaşdırmada və informatikada çox geniş yayılmışdır. Xüsusilə, onlar kompüter qrafikası və oyun mühərriklərində istifadə olunur. Məsələn, ekranda obyektin istənilən bucağa fırlanması fırlanma matrisindən istifadə etməklə proqramlaşdırıla bilər. İki ölçülü fəzada fırlanma matrisi belə görünür: Многомерные массивы - 6Burada teta obyektin fırlanması lazım olan bucaqdır. Bərabər ölçülü matrislər bir-birinə əlavə edilə bilər və əlavə element-element baş verir (eyni indekslərə malik elementləri əlavə edirik). Lakin matrisin vurulması əməliyyatı daha az tanışdır. Beləliklə, matrisləri çoxaltmaq və nəticədə əldə olunan matrisanı yalnız o halda əldə etmək olar ki, birinci matrisin sütunlarının sayı ikincinin sətirlərinin sayı ilə üst-üstə düşsün. Nəticə matrisinin birincisi ilə eyni sayda sətir və ikincisi ilə eyni sayda sütun olacaq. Vurma aşağıdakı kimi həyata keçirilir. Bizə bir matris a[l][m]b[m][n]. Onların çoxaldılması nəticəsində bir matris almalıyıq c[l][n]. c[0][0]Məhsul matrisinin elementini əldə etmək üçün a[0][0]birinci matrisin sıfır cərgəsinin sıfır elementini ikinci matrisin sıfır elementinə vurmalı, sonra birinci matrisin birinci sırasının birinci elementini birinci elementə vurmalısınız. ikinci matrisin birinci sütununun və s., bundan sonra bütün alınan məhsullar əlavə olunur.

a[0][0]*b[0][0] + a[0][1]*b[1][0] + … + a[0][m-1]*b[m-1][0]
Nəticə matrisinin birinci cərgəsinin ikinci elementini əldə etmək üçün ikinci sıra ilə eyni proseduru yerinə yetiririk

a[1][0]*b[0][0] + a[1][1]*b[0][1] + … + a[0][m-1]*b[m-1][0]
Və s. xəttin sonuna qədər. Sonra növbəti sətirə keçirik və xətlər bitənə qədər proseduru təkrarlayırıq. Yəni birinci matrisin sətirlərini ikinci matrisin sütunları ilə çarpırıq. Aşağıda matrisin çoxaldılması üçün kod verilmişdir. Siz onu sətir və sütunların sayı üzrə yuxarıda qeyd olunan şərtə uyğunluq yoxlaması ilə əlavə edə bilərsiniz.
//declaring two matrices
int [][] twoDimArray1 = {{1,0,0,0},{0,1,0,0},{0,0,0,0}};
int[][] twoDimArray2 = {{1,2,3},{1,1,1},{0,0,0},{2,1,0}};

//matrix multiplication process
int[][]twoDimArray3 = new int [twoDimArray1.length][twoDimArray2[0].length];
        for (int i=0; i<twoDimArray3[0].length; i++)
            for (int j=0; j<twoDimArray3.length; j++)
                for (int k=0; k<twoDimArray1[0].length; k++)
                              twoDimArray3[i][j] = twoDimArray3[i][j] + twoDimArray1[i][k] * twoDimArray2[k][j];

//output on display
        for (int i = 0; i < twoDimArray3.length; i++) {
            for (int j = 0; j < twoDimArray3[0].length; j++) {
                System.out.print(" " + twoDimArray3[i][j] + " ");
            }
            System.out.println();
        }
Proqram aşağıdakı nəticəni verir: 1 2 3 1 1 1 0 0 0

Düzbucaqlı olmayan ikiölçülü massivlər

İki ölçülü massivlər Java-da massivlər massivləri olduğundan daxili massivlərin hər biri müxtəlif uzunluqlarda ola bilər. Massiv yaradarkən biz sütunların sayını yox, yalnız sətirlərin sayını təyin edə bilərik (yəni əslində bu eyni sətirlərin uzunluğunu). Bir nümunəyə baxaq.
//declaring and creating an array, specifying only the number of rows
int [][] twoDimArray = new int[5][];

//initialize the array, filling it with arrays of different lengths
        twoDimArray[0] = new int[]{1, 2, 3, 4, 5};
        twoDimArray[1] = new int[]{1,2,3,4};
        twoDimArray[2] = new int[]{1,2,3};
        twoDimArray[3] = new int[]{1,2};
        twoDimArray[4] = new int[]{1};
//display the resulting non-rectangular two-dimensional array on the screen
        for (int i = 0; i < twoDimArray.length; i++) {
            for (int j = 0; j < twoDimArray[i].length; j++) {
                System.out.print(" " + twoDimArray[i][j] + " ");
            }
            System.out.println();
        }
Proqramın çıxışı: 1 2 3 4 5 1 2 3 4 1 2 3 1 2 1 Beləliklə, massivimizin sıfır sətirində massiv {1,2,3,4,5}, dördüncü sətirdə isə massiv var {1}.

Java-da üçölçülü massivlər

Sağlam düşüncəyə və Java dilinin məntiqinə əsasən, üçölçülü massivi “massivlər massivi” və ya “hər bir elementi iki ölçülü massiv olan massiv” adlandırmaq olar. Üstəlik, bu iki ölçülü massivlər fərqli ola bilər. Misal:
// create a three-dimensional array consisting of two two-dimensional arrays
int[][][] threeDimArr = new int[2][][];
//create the first 2D array of a 5x2 3D array
        threeDimArr[0] = new int[5][2];
//create a second 2D array of a 1x1 3D array
        threeDimArr[1] = new int[1][1];
Ancaq daha tez-tez praktikada hər üç kəmiyyətin bir anda təyin olunduğu üç ölçülü massivlər var, düzbucaqlı iki ölçülü massivlərin analoqu. Многомерные массивы - 7Artıq qeyd etdiyimiz kimi, üçölçülü və ya daha çox massivlər çox nadir hallarda istifadə olunur. Bununla belə, siz 3D massivi ilə maraqlı bir şey proqramlaşdıra bilərsiniz. Məsələn, çoxmərtəbəli avtomobil dayanacağı. Hər bir mərtəbə iki ölçülü massiv hesab edilə bilər və park yeri üçölçülü massivin xüsusi elementi hesab edilə bilər. Belə massivin elementi boşluq olduğu halda false , boşluq olduğu halda isə trueboolean dəyəri olan tiplə təmsil oluna bilər.
//set a boolean three-dimensional array. This car park has 3 floors, each of which can accommodate 2x5 = 10 cars. By default, all cells are empty (false)
boolean[][][] parkingLot = new boolean[3][2][5];
//two cars arrived and parked on the ground floor in cell [1][0] and [1][3]
        parkingLot[0][1][0] = true;
        parkingLot[0][1][3] = true;

//Output the array to the console
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 2; j++) {
                for (int k = 0; k < 5; k++) {
                    System.out.print("arr[" + i + "][" + j + "][" + k + "] = " + parkingLot[i][j][k] + "\t");

                }
                System.out.println();
            }
        }

Java proqramçısının real işində çoxölçülü massivlər

Əslində, əksər Java tərtibatçıları çoxölçülü massivlərlə tez-tez qarşılaşmırlar. Bununla belə, bu məlumat strukturunun çox yaxşı uyğunlaşdığı bir sıra vəzifələr var.

  1. Testlər və müəyyən bir alqoritmi yoxlamaq üçün matrisləri sabitlər kimi təyin etmək üçün.
  2. Bəzən neyron şəbəkələri üçün çoxölçülü massivlərdən istifadə olunur.
  3. Çoxölçülü massivlər arxivçilər üçün uyğundur.
  4. Şəkillərlə işləmək.

İkiölçülü və üçölçülü massivlərə dair maraqlı məsələlər

Siz Java-da çoxölçülü massivlər haqqında kifayət qədər məlumatınız var və əgər özünüzü əmin hiss edirsinizsə, aşağıdakı problemlərin bəzilərini həll etməyə cəhd edə bilərsiniz. Onlar asan deyil, lakin maraqlıdır. X O oyunu. 3x3 sahə qurun, növbə ilə gələn iki oyunçu yaradın. Əvvəlcə sahə boşdur və boş sahələrin hər birində birinci oyunçu xaç, ikincisi isə sıfır qoya bilər. Qalib ilk olaraq bir sıra, bir sütun və ya diaqonal olaraq düzülmüş üç xaç və ya üç sıfır toplayandır. Lenqton qarışqası . Hüceyrələrə bölünmüş müəyyən bir sahə var (iki ölçülü massiv), qara və ya ağ rəngə boyanmış (təsadüfi bir funksiya ilə təyin edilə bilər). Hüceyrələrdən birində təsadüfi olaraq “qarışqa” əmələ gəlir və hər addımda dörd istiqamətdən birində qonşu hüceyrəyə üfüqi və ya şaquli istiqamətdə hərəkət edə bilir. Qarışqaların hərəkət qaydaları:
  • Qara kvadratda qarışqa 90° sola dönməli, hücrəsinin rəngini ağa dəyişməli, sonra növbəti kvadrata doğru irəliləməlidir.
  • Ağ kvadratda qarışqa 90° sağa dönür və hüceyrəsinin rəngini qara rəngə dəyişir, sonra növbəti kvadrata doğru irəliləyir.
nQarışqanın ilkin mövqeyini nəzərə alaraq addım nömrəsində iterasiyanı hesablayan üsul yazın . Sahə təsadüfi olaraq sıfırlar və birlərlə doldurula bilər (yaxud şahmat taxtası nümunəsində etdiyimiz kimi Wvə hərfləri ilə qeyd olunur). BDaha iki parametrə ehtiyacımız var - qarışqanın üfüqi və şaquli mövqeyi, eləcə də bu addımda istiqaməti (şimal, cənub, qərb, şərq), qarışqa standart olaraq şimala baxır. Üç ölçülü massivlərdən istifadə edərək Rubik kubunu modelləşdirməyə cəhd edə bilərsiniz. Standart Rubik kubunun 6 üzü var və hər biri rəngli kvadratlardan ibarət üçölçülü massivdir Color[][][] rubik = new Color[6][3][3]. Bununla belə, Rubik kubunu həyata keçirmək heç də əhəmiyyətsiz bir iş deyil.

Massivlər haqqında faydalı materiallar

JavaRush-da bir çox məqalə massivlərə həsr edilmişdir (əsasən bir ölçülü olanlar, çünki onlar praktikada daha çox istifadə olunur). Onlara diqqət yetirin.
  1. Java-da massivlər - nümunələri ilə başlayanlar üçün massivlər haqqında
  2. Massivlər haqqında bir şey - Massivlər haqqında yaxşı ətraflı məqalə
  3. Arrays sinfi və onun istifadəsi - məqalədə sinfin bəzi üsulları təsvir edilmişdirArray
  4. Massivlər massivlərə həsr olunmuş ilk JavaRush mühazirəsidir.
  5. Sıfır uzunluqlu massivi qaytarın, null deyil - Effektiv Proqramlaşdırma müəllifi Joshua Bloch boş massivləri necə daha yaxşı qaytarmaq barədə danışır
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION