440 likes | 607 Views
Java. The Art and Science of. An Introduction. to Computer Science. ERIC S. ROBERTS. C H A P T E R 1 1. Arrays and ArrayLists. Little boxes, on a hillside, little boxes made of ticky-tacky Little boxes, little boxes, little boxes, all the same
E N D
Java The Art and Science of An Introduction to Computer Science ERIC S. ROBERTS C H A P T E R 1 1 Arrays and ArrayLists Little boxes, on a hillside, little boxes made of ticky-tacky Little boxes, little boxes, little boxes, all the same There’s a green one and a pink one and a blue one and a yellow one And they're all made out of ticky-tacky and they all look just the same —Malvina Reynolds, “Little Boxes,” 1962 Chapter 11—Arrays and ArrayLists Lecture Slides, Part IV CS101 @ Özyeğin University Slides are adapted from the originals available at http://www-cs-faculty.stanford.edu/~eroberts/books/ArtAndScienceOfJava/
In Java, you can create a multidimensional array by using multiple brackets in both the type and the initialization parts of the declaration. For example, you can create array space for a 3x3 tic-tac-toe board using the following declaration: char[][] board = new char[3][3]; • This declaration creates a two-dimensional array of characters that is organized like this: board[0][0] board[0][1] board[0][2] board[1][0] board[1][1] board[1][2] board[2][0] board[2][1] board[2][2] Multidimensional Arrays • Because the elements of an array can be of any Java type, those elements can themselves be arrays. Arrays of arrays are called multidimensional arrays.
Memory Layout char[][] board = new char[3][3]; board 0 0 0 0 0 1 2 1 0 0 0 2 0 1 2 0 0 0 0 1 2
Memory Layout char[][] board = new char[3][3]; board[0][0] = ‘X’; board ‘X’ 0 0 0 0 1 2 1 0 0 0 2 0 1 2 0 0 0 0 1 2
Memory Layout char[][] board = new char[3][3]; board[0][0] = ‘X’; board[1][0] = ‘O’; board ‘X’ 0 0 0 0 1 2 1 ‘O’ 0 0 2 0 1 2 0 0 0 0 1 2
Memory Layout char[][] board = new char[3][3]; board[0][0] = ‘X’; board[1][0] = ‘O’; board[2][1] = ‘X’; board ‘X’ 0 0 0 0 1 2 1 ‘O’ 0 0 2 0 1 2 0 ‘X’ 0 0 1 2
Exercise 1 int[][] matrix = new int[3][4]; matrix (B) matrix (A) 0 0 0 0 0 0 0 0 1 2 0 1 2 3 0 0 0 0 0 0 0 0 0 1 1 0 1 2 0 0 0 2 2 0 1 2 3 3 0 1 2 0 0 0 0 0 0 0 0 1 2 3 0 1 2
Exercise 2 int[][] matrix = new int[3][4]; matrix[3][4] = 42; println(matrix[0][0] + matrix[3][4]); (A) 0 (B) 42 (C) Error
Exercise 3 int[][] matrix = new int[3][4]; println(matrix.length); (A) 4 (B) 3 (C) 12 (D) 7
Exercise 4 int[][] matrix = new int[3][4]; println(matrix[0].length); (A) 4 (B) 3 (C) 12 (D) 7
Exercise 5 int[][] matrix = new int[3][4]; println(matrix[2].length); (A) 4 (B) 3 (C) 12 (D) 7
Traversing a two-dimensional array int[][] matrix = new int[3][4]; for(inti = 0; i < matrix.length; i++) { for(int j = 0; j < matrix[0].length; j++) { matrix[i][j] = i * j; } } matrix 0 0 0 0 0 0 1 2 3 1 0 1 2 3 2 0 1 2 3 0 2 4 6 0 1 2 3
Exercise 6 int[][] matrix = new int[3][4]; for(inti = 0; i < matrix.length; i++) { for(int j = 0; j < matrix[0].length; j++) { matrix[i][j] = ???; } } matrix (A)i + j 0 1 2 3 0 (B)i * j 0 1 2 3 1 1 2 3 4 (C)matrix.length + j 2 0 1 2 3 (D)matrix[0].length + i 2 3 4 5 0 1 2 3
Exercise 7 int[][] matrix = new int[3][4]; for(inti = 0; i < matrix.length; i++) { for(int j = 0; j < matrix[0].length; j++) { matrix[i][j] = ???; } } matrix (A)i + j 0 1 2 3 0 (B)matrix.length*i + j 0 1 2 3 1 4 5 6 7 (C)matrix[0].length*i+j 2 0 1 2 3 (D)matrix.length*j + i 8 9 10 11 0 1 2 3
Exercise 8 int[][] matrix = new int[3][4]; for(inti = 0; i < matrix.length; i++) { for(int j = 0; j < matrix[0].length; j++) { matrix[i][j] = ???; } } matrix (A)matrix[0].length*j+i 0 3 6 9 0 (B)matrix.length*i + j 0 1 2 3 1 1 4 7 10 (C)matrix[0].length*i+j 2 0 1 2 3 (D)matrix.length*j + i 2 5 8 11 0 1 2 3
Exercise 9 int[][] matrix = new int[3][3]; for(inti = 0; i < matrix.length; i++) { for(int j = 0; j < matrix[0].length; j++) { if(i >= j) { matrix[i][j] = 1; } } } 1 1 1 0 1 1 (A) (B) 0 1 1 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 (C) (D) 1 1 0 1 0 0 1 1 1 1 1 0
Image Processing • Images consist of a set of pixels arranged in a two-dimensional array, as shown in the expanded image. • In the ACM library, images are represented using the GImage class. GImage logo = new GImage("JTFLogo.gif"); add(logo);
The next three bytes indicate the amount of red, green, and blue in the pixel, in which each value varies from 0 to 255. Together, these three bytes form the RGB value of the color, which is typically expressed using six hexadecimal digits. The color in the example has the RGB value 0x996633, which is a light brown: Pixel Values • Each individual element in a pixel array is an int in which the 32 bits are interpreted as follows: 1 1 1 1 1 1 1 1 1 0 0 1 1 0 0 1 0 1 1 0 0 1 1 0 0 0 1 1 0 0 1 1 transparency (α) red green blue • The first byte of the pixel value specifies the transparency of the color.
Fully transparent colors are particularly useful in images, because they make it possible to display images that do not have rectangular outlines. For example, if the gray pixels in the corners of the JTFLogo.gif image have an alpha value of 0, the background will show through those parts of the logo. Transparency • The first byte of the pixel value specifies the transparency of the color, which indicates how much of the background shows through. This value is often denoted using the Greek letter alpha (α). • Transparency values vary from 0 to 255. The value 0 is used to indicate a completely transparent color in which only the background appears. The value 255 indicates an opaque color that completely obscures the background. The standard color constants all have alpha values of 255.
Image Manipulation pixel at (i,j) pixel at (height-i-1,j)
publicint[][] mirrorVertically(int[][] pixels) { int w = pixels[0].length; int h = pixels.length; int[][] result = newint[h][w]; for(inti = 0; i < result.length; i++) { for(int j = 0; j < result[0].length; j++) { result[h - i - 1][j] = pixels[i][j]; } } return result; }
publicvoid run() { // Images must be placed under the following folder: // workspace -> CS101 -> bin // assuming that your project is called "CS101" GImageyoda = newGImage("yoda.jpg"); // centralize the location of the image yoda.setLocation((getWidth() - yoda.getWidth())/2, (getHeight() - yoda.getHeight())/2); add(yoda); pause(1000); int[][] pixels = getImagePixels(yoda); int[][] newPixels = mirrorVertically(pixels); setImagePixels(yoda, newPixels); }
/********************************************************* * Methods given below are helper methods. * Do not try to understand their details. *********************************************************/ /* This method sets the pixels of the given GImage object * to the given pixel array. * Ignore the implementation details. */ publicvoidsetImagePixels(GImageimg, int[][] newPixels) { int w = newPixels[0].length; int h = newPixels.length; int[] pixels = newint[w*h]; for(int i = 0; i < h; i++) { for(int j = 0; j < w; j++) { pixels[i * w + j] = newPixels[i][j]; } } BufferedImage image = newBufferedImage(w, h, BufferedImage.TYPE_INT_RGB); image.setRGB(0, 0, w, h, pixels, 0, w); img.setImage(image); img.setBounds((getWidth() - w)/2, (getHeight() - h)/2, w, h); } /* This method reads the pixels of the given GImage * and returns them as a two-dimensional array. * Ignore the implementation details */ publicint[][] getImagePixels(GImageimg) { int w = (int)img.getWidth(); int h = (int)img.getHeight(); int[] pixels = newint[w*h]; PixelGrabberpg = newPixelGrabber(img.getImage(), 0, 0, w, h, pixels, 0, w); try { pg.grabPixels(); } catch (InterruptedException e) { println("Problem occurred. Contact the coursestaff!"); } int[][] result = newint[h][w]; for(int i=0; i < h; i++) { for(int j=0; j < w; j++) { result[i][j] = pixels[i*w + j]; } } returnresult; } publicvoidinit() { setSize(600, 450); }
Rotate 180 Degrees pixel at (i,j) pixel at (height-i-1, width-j-1)
publicint[][] rotate180Degrees(int[][] pixels) { int w = pixels[0].length; int h = pixels.length; int[][] result = newint[h][w]; for(inti = 0; i < result.length; i++) { for(int j = 0; j < result[0].length; j++) { result[h - i -1][w - j - 1] = pixels[i][j]; } } returnresult; }
Mirror Horizontally (self-exercise) pixel at (i,j) pixel at (?,?)
Rotate Clockwise (self-exercise) pixel at (i,j) pixel at (?,?) What’s the width and height of the new image?
Green Screen Replacement F B R if F(i,j) is not green R(i,j) = F(i,j) else R(i,j) = B(i,j) A color (r,g,b) is considered green when r < 50, b < 50, and g > 100.
publicint[][] greenScreenEffect(int[][] foreground, int[][] background) { ??? }
publicvoid run() { GImage superman = newGImage("superman.jpg"); GImageistanbul = newGImage("istanbul.jpg"); // centralize the location of the image superman.setLocation((getWidth() - superman.getWidth())/2, (getHeight() - superman.getHeight())/2); add(superman); pause(1000); int[][] supermanPixels = getImagePixels(superman); int[][] istanbulPixels = getImagePixels(istanbul); int[][] newSupermanPixels = greenScreenEffect(supermanPixels, istanbulPixels); setImagePixels(superman, newSupermanPixels); }
/********************************************************* * Methods given below are helper methods. * Do not try to understand their details. *********************************************************/ /* Returns the red color component of a given pixel value * Ignore the implementation details. */ publicintgetRedComponent(int pixel) { return (pixel >> 16) & 0xff; } /* Returns the green color component of a given pixel value * Ignore the implementation details. */ publicintgetGreenComponent(int pixel) { return (pixel >> 8) & 0xff; } /* Returns the blue color component of a given pixel value * Ignore the implementation details. */ publicintgetBlueComponent(int pixel) { return pixel & 0xff; }
Black and Whiten (self-exercise) Use the getRed/Green/BlueComponent methods to decide if a pixel is dark or light. Use pixel value 0xFFFFFF for white, 0 for black.
Lights Out • http://en.wikipedia.org/wiki/Lights_Out_%28game%29
publicclassLightsOutextendsGraphicsProgram { privateRandomGeneratorrgen = RandomGenerator.getInstance(); privatestaticfinalintDIMENSION = 5; // we have a dim x dim board privatestaticfinalintLIGHT_SIZE = 40; privateGRect[][] lights = newGRect[DIMENSION][DIMENSION]; publicvoid run() { initializeLights(); } publicvoidinitializeLights() { for(inti=0; i < lights.length; i++) { for(int j=0; j < lights[0].length; j++) { lights[i][j] = newGRect(j * LIGHT_SIZE, i * LIGHT_SIZE, LIGHT_SIZE, LIGHT_SIZE); lights[i][j].setFilled(false); lights[i][j].setFillColor(Color.GRAY); add(lights[i][j]); } } // You may start with various initial conditions }
publicvoidtoggleLight(inti, int j) { if(i >= 0 && i < lights.length && j >= 0 && j < lights[0].length) { booleanisOff = lights[i][j].isFilled(); lights[i][j].setFilled(!isOff); } } publicvoidpressOnLight(inti, int j) { toggleLight(i,j); toggleLight(i-1, j); toggleLight(i+1, j); toggleLight(i, j-1); toggleLight(i, j+1); if(isPuzzleSolved()) { GLabellbl = newGLabel("SOLVED!", 0, 0); lbl.setFont("Courier-36"); lbl.setColor(Color.WHITE); lbl.setLocation((getWidth()-lbl.getWidth())/2, getHeight()/2); add(lbl); } }
publicbooleanisPuzzleSolved() { for(inti=0; i < lights.length; i++) { for(int j=0; j < lights[0].length; j++) { if(!lights[i][j].isFilled()) { // light is lit returnfalse; } } } returntrue; }
// This method is invoked whenever the user presses the mouse button // The method finds out which light is pressed on // and invokes the pressOnLight() method publicvoid mousePressed(MouseEvent e) { int x = e.getX(); int y = e.getY(); int i = y / LIGHT_SIZE; int j = x / LIGHT_SIZE; pressOnLight(i, j); } publicvoid init() { setSize(DIMENSION * LIGHT_SIZE, DIMENSION * LIGHT_SIZE); addMouseListeners(); }
Heat Transfer • A space can be considered as a collection of cells. • Each cell has a temperature. • Each cell transfers heat from/to its neighbors. • Compute this equation for each cell, forever. Σ High k: quick transfer Low k: slow transfer Tnew = Told + k(TN – Told) N is a neighbor
For example, you can declare and initialize a multiplication table for the digits 0 to 9 like this: private static int[][] MULTIPLICATION_TABLE = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 }, { 0, 3, 6, 9, 12, 15, 18, 21, 24, 27 }, { 0, 4, 8, 12, 16, 20, 24, 28, 32, 36 }, { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45 }, { 0, 6, 12, 18, 24, 30, 36, 42, 48, 56 }, { 0, 7, 14, 21, 28, 35, 42, 49, 56, 63 }, { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72 }, { 0, 9, 18, 27, 36, 45, 54, 63, 72, 81 } }; Initializing Multidimensional Arrays • You can initialize a multidimensional array when you declare it by using nested braces to reflect the levels of array nesting.
Exercise: Multidimensional Arrays Write a single Java statement that declares and initializes a two-dimensional array named chessboard so that the array contains a representation of the initial position in a game of chess: The individual elements should be characters using the standard symbols for the pieces:
Solution: Chessboard Problem private char[][] chessboard = { { 'r', 'n', 'b', 'q', 'k', 'b', 'n', 'r' }, { 'p', 'p', 'p', 'p', 'p', 'p', 'p', 'p' }, { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' }, { 'R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R' }, };