4/10 lecture sketch announcements + Review session R3: Monday, 4/16, 7-9pm, Olin Hall 155 + tky out of town thursday after lecture until monday evening topics + r-value versus l-value. key point: location of a variable is not a(n r)-value + bigger 1-d array/method example: pascal's triangle + 2-dimensional java arrays + java strings ! includes additional, helpful material on strings ! $toCharArray$, $new String(...)$ ! bigger example next lecture: object-oriented programming -- not on prelim T3! + $class$ = $static$ versus instance = non-static + $public$ versus $private$ + objects _______________________________________________________________________________ r-value versus l-value + recall, in box scope diagram: a variable = named box containing a value + variable has two kinds of "values" + *r-value* = *value* = the contents of the "box" + note: do not confuse a reference (a value in java) with the object (not a value in java) it points to! + *l-value* = the "box" + note: not a reference (in java) + note: not a(n r-)value _______________________________________________________________________________ bigger 1D example: $n$-th row pascal's triangle matlab, vectorized: i = 0; row = 1; while i < n row = [row 0] + [0 row]; i = i+1; end matlab, unvectorized, without $for$ loops: i = 0; row = 1; while i < n i = i+1; newrow = zeros(1, i+1); j = 1; while j <= length(newrow) if j < i+1, newrow(j) = newrow(j) + row(j); end if 1 < j, newrow(j) = newrow(j) + row(j-1); end j = j+1; end row = newrow; end java code segment, assuming no pre-defined variables: int i = 0; int[] row = new int[] { 1 } ; while (i < n) { i = i+1; // <-- note: no $int$ in front! int[] newrow = new int[i+1]; int j = 0; while (j < newrow.length) { if (j < i) { newrow[j] = newrow[j] + row[j]; } // <-- note: no if (0 < j) { newrow[j] = newrow[j] + row[j-1]; } // <-- $int[]$ j = j+1; } row = newrow; } java method $nextrow(row)$ and main method in a class: public class L4_10 { public static void main(String[] args) { int[] ans = nextrow(new int[] { 1, 3, 3, 1 }); } public static int[] nextrow(int[] row) { int[] newrow = new int[1+row.length]; int j = 0; while (j < newrow.length) { if (j < row.length) { newrow[j] = newrow[j] + row[j]; } if (0 < j) { newrow[j] = newrow[j] + row[j-1]; } j = j+1; } return newrow; } } trace! note: *always* (e.g. on exam) draw in length of the array -- field [4/17] note: to save space, below, arrays are drawn inside class $L4_10$, but they really belong inside class $Object$. 1. before code runs class L4_10 ++=========++ || main || || nextrow || ++=========++ 2. start running $main$: draw activation record, parameters class L4_10 ++====================================================++ || main || || nextrow || || || || main || || +------------------------------------------------+ || || | +----------+ | || || | args | (ignore) | | || || | +----------+ | || || +------------------------------------------------+ || ++====================================================++ 3. run $main$'s body in activation record: create new array, call $nextrow$ class L4_10 ++====================================================++ || main +---+---+---+---+ 4 || || nextrow | 1 | 3 | 3 | 1 | || || +---+---+---+---+ || || main /|\ || || +--------------------------------+---------------+ || || | +----------+ | | || || | args | (ignore) | | | || || | +----------+ | | || || | +---+ | | || || | ans | | * | || || | +---+ _________/\__________ | || || | / \ | || || | int[] ans = nextrow(new int[] { 1, 3, 3, 1 }); | || || +------------------------------------------------+ || ++====================================================++ 4. start running $nextrow$: draw activation record, parameters class L4_10 ++====================================================++ || main +---+---+---+---+ 4 || || nextrow +-> | 1 | 3 | 3 | 1 | || || | +---+---+---+---+ || || main | || || +----------------------+----+ || || | +----------+ | | || || | args | (ignore) | | | || || | +----------+ | | || || | +---+ | | || || | ans | | | | || || | +---+ | | || || | ??? | | || || | int[] ans = nextrow( * ); | || || +----------------------+----+ || || nextrow | || || +----------------------+-------------------------+ || || | +---+ | | || || | row | *-+-----------+ | || || | +---+ | || || | | || || | int[] newrow = new int[1+row.length]; | || || | int j = 0; | || || | while (j < newrow.length) { | || || | if (j| 1 | 3 | 3 | 1 | || || | +---+ | | +---+---+---+---+ || || | ??? | | || || | int[] ans = nextrow(...); | | +---+---+---+---+---+ 5 || || +---------------------------+ | +->| 0 | 0 | 0 | 0 | 0 | || || nextrow | | +---+---+---+---+---+ || || +------------------------------+---+-------------+ || || | +---+ | | | || || | row | *-+-------------------+ | | || || | +---+ | | || || | +---+ | | || || |newrow| *-+-----------------------+ | || || | +---+ | || || | +---+ | || || | j | 0 | | || || | +---+ | || || | | || || | int[] newrow = new int[1+row.length]; | || || | int j = 0; | || || | while (j < newrow.length) { | || || | if (j $j=1$ of loop: $j| 1 | 3 | 3 | 1 | || || | +---+ | | +---+---+---+---+ || || | ??? | | || || | int[] ans = nextrow(...); | | +-/-+---+---+---+---+ 5 || || +---------------------------+ | +->|0 1| 0 | 0 | 0 | 0 | || || nextrow | | /---+---+---+---+---+ || || +------------------------------+---+-------------+ || || | +---+ | | | || || | row | *-+-------------------+ | | || || | +---+ | | || || | +---+ | | || || |newrow| *-+-----------------------+ | || || | +---+ | || || | +-/-+ | || || | j |0 1| | || || | /---+ | || || | | || || | while (j < newrow.length) { | || || | if (j $j=2$ of loop: $j| 1 | 3 | 3 | 1 | || || | +---+ | | +---+---+---+---+ || || | ??? | | || || | int[] ans = nextrow(...); | | +---+-//-+---+---+---+ 5 || || +---------------------------+ | +->| 1 |01 4| 0 | 0 | 0 | || || nextrow | | +---//---+---+---+---+ || || +------------------------------+---+-------------+ || || | +---+ | | | || || | row | *-+-------------------+ | | || || | +---+ | | || || | +---+ | | || || |newrow| *-+-----------------------+ | || || | +---+ | || || | +-/-+ | || || | j |1 2| | || || | /---+ | || || | | || || | while (j < newrow.length) { | || || | if (j $j=3$ of loop: $j| 1 | 3 | 3 | 1 | || || | +---+ | | +---+---+---+---+ || || | ??? | | || || | int[] ans = nextrow(...); | | +---+---+-//-+---+---+ 5 || || +---------------------------+ | +->| 1 | 4 |03 6| 0 | 0 | || || nextrow | | +---+---//---+---+---+ || || +------------------------------+---+-------------+ || || | +---+ | | | || || | row | *-+-------------------+ | | || || | +---+ | | || || | +---+ | | || || |newrow| *-+-----------------------+ | || || | +---+ | || || | +-/-+ | || || | j |2 3| | || || | /---+ | || || | | || || | while (j < newrow.length) { | || || | if (j $j=4$ of loop: $j| 1 | 3 | 3 | 1 | || || | +---+ | | +---+---+---+---+ || || | ??? | | || || | int[] ans = nextrow(...); | | +---+---+---+-//-+---+ 5 || || +---------------------------+ | +->| 1 | 4 | 6 |03 4| 0 | || || nextrow | | +---+---+---//---+---+ || || +------------------------------+---+-------------+ || || | +---+ | | | || || | row | *-+-------------------+ | | || || | +---+ | | || || | +---+ | | || || |newrow| *-+-----------------------+ | || || | +---+ | || || | +-/-+ | || || | j |3 4| | || || | /---+ | || || | | || || | while (j < newrow.length) { | || || | if (j $j=5$ of loop: $j| 1 | 3 | 3 | 1 | || || | +---+ | | +---+---+---+---+ || || | ??? | | || || | int[] ans = nextrow(...); | | +---+---+---+---+-/-+ 5 || || +---------------------------+ | +->| 1 | 4 | 6 | 4 |0 1| || || nextrow | | +---+---+---+---/---+ || || +------------------------------+---+-------------+ || || | +---+ | | | || || | row | *-+-------------------+ | | || || | +---+ | | || || | +---+ | | || || |newrow| *-+-----------------------+ | || || | +---+ | || || | +-/-+ | || || | j |4 5| | || || | /---+ | || || | | || || | while (j < newrow.length) { | || || | if (j| 1 | 3 | 3 | 1 | || || | +---+ | | +---+---+---+---+ || || | *----------+--|---+ || || | int[] ans = nextrow(...); | | | +---+---+---+---+-/-+ 5 || || +---------------------------+ | +->| 1 | 4 | 6 | 4 |0 1| || || nextrow | | +---+---+---+---/---+ || || +------------------/-----------+---+-------------+ || || | +---+ / | | | || || | row | *-+-----/-------------+ | | || || | +---+ / | | || || | +---+ / | | || || |newrow| *-+--/--------------------+ | || || | +---+ / | || || | +-/-+/ | || || | j |4 5/ | || || | /--/+ | || || | / | || || | return/newrow; | || || +------/-----------------------------------------+ || ++======================================================================++ 12. finish assignment to $ans$: class L4_10 ++======================================================================++ || main || || nextrow || || || || main || || +---------------------------+ || || | +----------+ | || || | args | (ignore) | | || || | +----------+ | || || | +---+ | +---+---+---+---+ 4 || || | ans | *-+-----+ | +---->| 1 | 3 | 3 | 1 | || || | +---+ | | | +---+---+---+---+ || || | *----------+--|---+ || || | int[] ans = nextrow(...); | | | +---+---+---+---+-/-+ 5 || || +---------------------------+ | +->| 1 | 4 | 6 | 4 |0 1| || || nextrow | | +---+---+---+---/---+ || || +------------------/-----------+---+-------------+ || || | +---+ / | | | || || | row | *-+-----/-------------+ | | || || | +---+ / | | || || | +---+ / | | || || |newrow| *-+--/--------------------+ | || || | +---+ / | || || | +-/-+/ | || || | j |4 5/ | || || | /--/+ | || || | / | || || | return/newrow; | || || +------/-----------------------------------------+ || ++======================================================================++ note: you should now be able to do P6.5 _______________________________________________________________________________ 2D array in java = an array of arrays example: $int[][]$ = array of array of integers java code interleaved with pictures: possible matlab equivalent int[][] x = new int [2][3]; // x = zeros(2,3); // 0 1 2 3 // +---+ +---+---+---+ x 1 2 3 // x | *-+--->+---+ | 0 | 0 | 0 | +---+---+---+ // +---+ 0 | *-+--> +---+---+---+ 1 | 0 | 0 | 0 | // +---+ +---+---+---+ // 1 | *-+--> +---+---+---+ 2 | 0 | 0 | 0 | // +---+ | 0 | 0 | 0 | +---+---+---+ // 2 +---+---+---+ // 0 1 2 3 x[0][1] = 7; // x(1,2) = 7; // 0 1 2 3 // +---+ +---+---+---+ x 1 2 3 // x | *-+--->+---+ | 0 | 7 | 0 | +---+---+---+ // +---+ 0 | *-+--> +---+---+---+ 1 | 0 | 7 | 0 | // +---+ +---+---+---+ // 1 | *-+--> +---+---+---+ 2 | 0 | 0 | 0 | // +---+ | 0 | 0 | 0 | +---+---+---+ // 2 +---+---+---+ // 0 1 2 3 x[1][2] = 8; // x(2,3) = 8; // 0 1 2 3 // +---+ +---+---+---+ x 1 2 3 // x | *-+--->+---+ | 0 | 7 | 0 | +---+---+---+ // +---+ 0 | *-+--> +---+---+---+ 1 | 0 | 7 | 0 | // +---+ +---+---+---+ // 1 | *-+--> +---+---+---+ 2 | 0 | 0 | 8 | // +---+ | 0 | 0 | 8 | +---+---+---+ // 2 +---+---+---+ // 0 1 2 3 x[1] = x[0]; // no equivalent // 0 1 2 // +---+ +---+---+---+ // x | *-+--->+---+ | 0 | 7 | 0 | // +---+ 0 | *-+--> +---+---+---+ // +---+ +--^ // 1 | *-+-+ +---+---+---+ // +---+ | 0 | 0 | 8 | // 2 +---+---+---+ // 0 1 2 3 // $x[1]$, $x[0]$ are aliases. // array that was pointed to by $x[1]$ goes away after there are no // more references to it -- *garbage* *collection* x[1][0] = 9; // 0 1 2 // +---+ +---+---+---+ // x | *-+--->+---+ | 9 | 7 | 0 | // +---+ 0 | *-+--> +---+---+---+ // +---+ +--^ // 1 | *-+-+ +---+---+---+ // +---+ | 0 | 0 | 8 | // 2 +---+---+---+ // 0 1 2 3 // since $x[1]$, $x[0]$ are aliases, $x[1][0]$ is the same as $x[0][0]$ note: + array above is interpreted as being in *row-major* order -- major/primary grouping is into rows + could also interpret array above as as being in *column-major* order -- major/primary grouping is into columns, e.g. before aliasing: 0 1 2 +---+ +---+---+ x | *-+--->| * | * | +---+ +-+-+-+-+ | | V V +---+ +---+ 0 | 0 | | 0 | 0 +---+ +---+ 1 | 7 | | 0 | 1 +---+ +---+ 2 | 0 | | 8 | 2 +---+ +---+ 3 3 + java programs should clearly document (in comments) whether arrays are row-major or column-major since the choice is up to the programmer to choose which interpretation he/she wants _______________________________________________________________________________ java strings -- helpful for P6.2 one dimensional $char$ matrix (reference to) $String$ object + literals quoted within $'$s + literals quoted withn $"$s + maybe $nan$ + $null$ + null/empty string $''$ + $new String("")$ (or $""$) + horizontal concatenation $[s t]$ + $s + t$ + length $length(s)$ + $s.length()$ <-- note $()$ + *1-relative* indexing: 1.. + *0-relative* indexing: 0.. + read $i$-th character $s(i)$ + $s.charAt(i)$ + assign to $i$-th position $s(i)='h';$ + no equivalent: + use $StringBuffer$ or + build new string using concatenation + $upper(s)$, $lower(s)$ + $s.toUpperCase()$, $s.toLowerCase()$ + convert number to string $num2str(n)$ + $"" + n$ <-- Java being friendly + assignment $x = y;$ + $x = new String(y);$ <-- copy contents + no equivalent + $x = y;$ <-- copy reference, so both point to *same* string! !+ a string already is an array of + convert a string $x$ to an array ! characters of characters: $x.toCharArray()$ ! returns a reference to an "exploded" ! array of the characters in $s$ !+ an array of characters already is + convert an array $a$ of characters ! a string to an array: $new String(a)$ returns ! a reference to a new string with ! the same contents as $a$ ! !tip: for now, to modify a String: ! + convert it to an array of characters ! + modify the array ! + convert the array of characters back to a string _______________________________________________________________________________ box scope diagrams for arrays and Strings + technically, objects should be drawn in the class they belong to + technically, arrays belong to class $Object$, so all arrays are drawn in (the same) class $Object$ + strings belong to class $String$, so all strings drawn in class $String$ picture of an array and a reference to it: +---------------+ -------> | 0 1 2 | | +---+---+---+ | | | 2 | 7 | 5 | | | +---+---+---+ | | | | +---+ | | length | 3 | | | +---+ | +---------------+ it is like a matlab $struct$ -- it has variables (fields) inside it + $length$ is a variable/field that can be read, but cannot be assigned to + the elements of the array are accessed using $[$-$]$ notation instead of $.$-notation, e.g. $x[3]$ instead of $x.3$ + we will often be lazy: + draw the array within the same class where the method that creates it is defined, not within the activation record + just draw $length$ as a number off the end of the array: 0 1 2 3 +---+---+---+ -------> | 2 | 7 | 5 | +---+---+---+ picture of a String and a reference to it: +----------------------------+ -------> | (private data for "hello") | | length | | toUpperCase | | toLowerCase | | toCharArray | +----------------------------+ + there is private data that holds the characters + there are methods -- this is why we use $s.length()$ not $s.length$ for the length of a string: it is a method, not a variable + we will often be lazy: + draw the string as a literal (e.g. $"hello"$) in the same class where the method that creates it is defined, not within the activation record: -------> "hello" + think of calls like $"hello".toUpperCase()$ as giving the command "convert yourself to upper case" to the $"hello"$ String object: in general, when objects have methods, calling the method is like giving the object a command _______________________________________________________________________________ ! big String/char example: dna question from P2.3/P3.5 revisited matlab, vectorized: function [] = showmatch(top,bot) % [] = showmatch(top,bot): show matching (complementary) positions -- % print $top$ and $bot$ with non-matching in lower case, matching in upper, % and print positions of matches (top, bot are strands of DNA) % convert to lower case for display and ease of comparison top = lower(top); bot = lower(bot); % find matches using lookup table complement('atgc' + 0) = 'tacg'; match = top == complement(bot + 0); % Convert characters in matching positions to upper case. top(match) = upper(top(match)); bot(match) = upper(bot(match)); % display show results disp(['top: ' top]); disp(['bot: ' bot]); disp(['matching positions: [' num2str(find(match)) ']']); matlab, unvectorized: function [] = showmatch(top,bot) % [] = showmatch(top,bot): show matching (complementary) positions -- % print $top$ and $bot$ with non-matching in lower case, matching in upper, % and print positions of matches (top, bot are strands of DNA) % get lower case and upper case equivalents top = lower(top); bot = lower(bot); Top = upper(top); Bot = upper(bot); % find matches and convert corresponding characters to upper s = 'atgc'; t = 'tacg'; complement(255) = ' '; % create character array $complement(1:255)$ i = 0; while i < length(s) i = i+1; complement(s(i)+0) = t(i); end i = 0; match = logical(zeros(1,length(top))); while i < length(top) i = i+1; match(i) = top(i) == complement(bot(i) + 0); if match(i) % <-- $match(i)$ is already logical! top(i) = TOP(i); bot(i) = BOT(i); end end % display show results disp(['top: ' top]); disp(['bot: ' bot]); disp(['matching positions: [' num2str(find(match)) ']']); java, as a class with a main method: class P23__P35 { public static void main(String[] args) { showmatch(new String("taCaGCgATAcgtg"), new String("agTActTgATgtgC")); } /* show matching (complementary) positions of strands of DNA: print $top$, $bot$ with non-matching in lower case, matching in upper, and print positions of matches */ public static void showmatch(String top, String bot) { // get lower case character array and upper case equivalents char[] ctop = top.toLowerCase().toCharArray(); char[] cbot = bot.toLowerCase().toCharArray(); String Top = top.toUpperCase(); String Bot = bot.toUpperCase(); // find matches and convert corresponding characters to upper String s = new String("atgc"); String t = new String("tacg"); char[] complement = new char[256]; int i = 0; while (i < s.length()) { complement[(int) (s.charAt(i))] = t.charAt(i); i = i+1; } i = 0; boolean[] match = new boolean[ctop.length]; while (i < ctop.length) { match[i] = ctop[i] == complement[(int) (cbot[i])]; if (match[i]) { // <-- $match[i]$ is already boolean! ctop[i] = Top.charAt(i); cbot[i] = Bot.charAt(i); } i = i+1; } // display show results System.out.println("top: " + new String(ctop)); System.out.println("bot: " + new String(cbot)); System.out.print("matching positions: ["); i = 0; while (i < match.length) { if (match[i]) { System.out.print(" " + i); } i = i+1; } System.out.println(" ]"); } } notes: ask $top$ to create a new String with all letters in lower case and return a reference to the new string ______/\_______ / \ + $top.toLowerCase().toCharArray()$ \_____________ ______________/ \/ tell lower case string to create a new character array with the same contents (characters) and return a reference to the new array more long winded version of $ctop = top.toLowerCase().toCharArray();$: String tmp = top.toLowerCase(); ctp = tmp.toCharArray(); + $(int) (cbot[i])$ -- good style to fully parenthesize when casting since $(int) cbot[i]$ probably means $((int) cbot) [i]$. + $if (match[i])$ just uses $match[i]$ instead of $match[i] == true$: it is good style to use boolean values directly. (use $!match[i]$, not $match[i] == false$ or $match[i] != true$.) + $"top: " + new String(ctop))$ needs the explicit conversion to a string -- $"top: " + ctop$ uses the address of $ctop$ (i think) _______________________________________________________________________________ questions (some from 4/05) Q: if you declare $x$ to be $double$, can you change it to another type, Q: e.g. $int$? A: no. Q: does java have $inf$? A: yes, there is $Double.POSITIVE_INFINITY$ and $Double.NEGATIVE_INFINITY$, A: and $1.0/0.0$ and $-1.0/0.0$ also work. A: $Double.NaN$ is the java equivalent of matlab's $nan$. Q: when you create an array, do its elements get initialized? A: yes: $int$s get $0$, $double$s get $0.0$, $boolean$s get $false$, A: $char$s get something called the "null character", which we mostly A: never use in cs100M. Q: what else besides $new ...$ could one put as the initial value of an array? A: any reference, thus in method $nextrow$, instead of assigning a reference A: to a new array to $newrow$, we could have assigned $row$. Q: (the trace drawn in lecture:) if $ans$ is in the same class as $nextrow$, Q: why isn't the activation record for $nextrow$ in the same box as $ans$? A: code lives inside methods, so i was assuming the call to $nextrow$ was in A: a method defined in the same class. thus, the two activation methods A: --for $main$ and $nextrow$-- *are* in the same class. the box drawn around A: $ans$ in lecture was the unlabeled activation record for $main$. sorry about A: the confusion. Q: can you use the curly braces to specify the values of a 2D array? A: yes. from the 4/05 lecture sketch, here is a way to create the java A: equivalent of $[7 3; 2 4]$ in row major order: A: $new int[][] { new int[] { 7, 3 }, new int[] { 2, 4 } }$. A: observe that the syntax is the same -- to create an array, A: you need $new$, the type of the array (e.g. $int[][]$ or $int[]$), A: and the values separated by commas inside braces. the values can A: themselves be references to arrays. Q: should we cross out objects to which all references are lost? A: only if we ask you to. otherwise, don't bother. Q: what does $new$ mean in the array declaration-and-initialization examples? A: $new$ is used to create new objects. $new$ is followed by the type of object, A: e.g. $int[]$ for an array of integers. one can either specify the length A: of the array within the brackets (e.g. $new int[4]$) or one can specify the A: contents of the array (e.g. $new int[] { 1, 3, 3, 1 }$), in which case you A: do not need to (perhaps are not allowed to) specify the length. Q: can you draw the 2D array the other way (column- instead of row-major)? A: yes; see notes above.