1 Arrays: Matrix Renamed Instructor: Mainak Chaudhuri [email protected].

43
1 Arrays: Matrix Renamed Instructor: Mainak Chaudhuri [email protected]

Transcript of 1 Arrays: Matrix Renamed Instructor: Mainak Chaudhuri [email protected].

1

Arrays: Matrix Renamed

Instructor: Mainak [email protected]

2

Arrays• Till now we are able to declare and

initialize few variables• Reality: need to compute on a large

amount of data• Arrays are data structures that can

hold a series of values– Just a new name for matrix– Just like a matrix index, an array uses an

index to access a particular value

3

Initializing an arrayint justAVector[] = {2, 3, 5, 7, 11, 13,

17, 19, 23, 29};String myFriendsNames[] = {“John”,

“Brian”, “Jill”, “Jack”, “Ivan”};char firstFewDigits[] = {‘0’, ‘1’, ‘2’, ‘3’};boolean whichOfMyFriendsAreTall[] =

{false, false, true, true, false};• Size of an array

array_name.length

4

Finding averageclass Average { public static void main (String arg[]) { double dailyRainFall[] = {12.3, 13.5, 4.2,

2.4, 1.1, 0, 10.8}; int i; float average = 0;

for (i=0; i<7; i++) { average += dailyRainFall[i]; } average /= 7; System.out.println (“Average rain fall: ”

+ average + “ mm”); }}

5

Finding maximumclass Maximum { public static void main (String arg[]) { int n = 100; double numbers[] = new double[n];

Initialize (numbers, n); System.out.println (“Maximum: ” +

FindMax (numbers, n)); }

6

Finding maximum public static void Initialize (double

numbers[], int length) { int i; for (i=0; i<length; i++) { numbers[i] =

Math.sin(2*Math.PI/(i+1)) + Math.cos(2*Math.PI/(i+2));

} }

7

Finding maximum public static double FindMax (double

numbers[], int length) { double max = numbers[0]; int i;

for (i=1; i<length; i++) { if (numbers[i] > max) { max = numbers[i]; } } return max; }} // end class

8

Finding maximum• Want to print the position of the

maximum also– Need to return two values from FindMax– Use a 2-element array as return type– Shows why returning local reference does

not work– Shows the distinction between two

different memory areas: stack and heap

9

Finding max and max indexclass Maximum { public static void main (String arg[]) { int n = 100; double numbers[] = new double[n]; double result[];

Initialize (numbers, n); result = FindMax (numbers, n); // Danger! System.out.println ("Maximum: " +

result[0] + ", Position: " + (int)result[1]); }

10

Finding max and max index public static void Initialize (double

numbers[], int length) { int i; for (i=0; i<length; i++) { numbers[i] =

Math.sin(2*Math.PI/(i+1)) + Math.cos(2*Math.PI/(i+2));

} }

11

Finding max and max index public static double[] FindMax (double

numbers[], int length) { // Does not work double result[] = {numbers[0], 0}; int i;

for (i=1; i<length; i++) { if (numbers[i] > result[0]) { result[0] = numbers[i]; result[1] = i; } } return result; // Local reference on stack }} // end class

12

Finding max and max index public static double[] FindMax (double numbers[],

int length) { // This one works double result[] = new double[2]; // On heap result[0] = numbers[0]; result[1] = 0; int i;

for (i=1; i<length; i++) { if (numbers[i] > result[0]) { result[0] = numbers[i]; result[1] = i; } } return result; // Reference on heap }} // end class

13

Array layout in memory• Recall that every variable requires

some space to be stored in memory– Often the compiler is responsible for

allocating this space– In other words, every variable has an

address (just like you and I have addresses)

– The address is often called a reference of a variable in Java

– If I try to print the value at this address, I will get the value of the variable

• How is an array stored in memory?

14

Array layout in memory• The array elements are stored

contiguously in memory– numbers[0], numbers[1], …– Starting address is numbers (same as the

address of numbers[0]), add 8 to get the address of numbers[1]

– doubles are 64 bits in size and memory is always byte addressed (one byte is 8 bits)

– Putting array names in method arguments is equivalent to passing the arrays by reference: modifications to arrays inside the method are reflected outside the method

– Of course, it is possible to pass individual array elements (not by reference, but by value i.e. as private copies)

15

FindMax: reference as a valueclass Maximum { // Still pass by value

public static void main (String arg[]) { int n = 100; double numbers[] = new double[n]; double result[] = new double[2];

Initialize (numbers, n); result[0] = numbers[0]; result[1] = 0; FindMax (numbers, n, result); // reference System.out.println ("Maximum: " +

result[0] + ", Position: " + (int)result[1]); }

16

FindMax: reference as a value public static void Initialize (double

numbers[], int length) { int i; for (i=0; i<length; i++) { numbers[i] =

Math.sin(2*Math.PI/(i+1)) + Math.cos(2*Math.PI/(i+2));

} }

17

FindMax: reference as a value public static void FindMax (double

numbers[], int length, double r[]) { int i;

for (i=1; i<length; i++) { if (numbers[i] > r[0]) { r[0] = numbers[i]; r[1] = i; } } }} // end class

18

FindMax: passing valuesclass Maximum { // This example does not

work public static void main (String arg[]) { int n = 100; double numbers[] = new double[n]; double result[] = new double[2];

Initialize (numbers, n); result[0] = numbers[0]; result[1] = 0; FindMax (numbers, n, result[0], result[1]); System.out.println ("Maximum: " + result[0]

+ ", Position: " + (int)result[1]); }

19

FindMax: passing values public static void Initialize (double

numbers[], int length) { int i; for (i=0; i<length; i++) { numbers[i] =

Math.sin(2*Math.PI/(i+1)) + Math.cos(2*Math.PI/(i+2));

} }

20

FindMax: passing values public static void FindMax (double

numbers[], int length, double max, double position) {

int i;

for (i=1; i<length; i++) { if (numbers[i] > max) { max = numbers[i]; position = i; } } }} // end class

21

Always pass by value• Java always passes arguments by value

– References are just a special kind of values– Modifying a value in a method does not

have any effect on the caller– Modifying a value pointed to by a

reference in a method does change the value in the caller also• References are addresses and hence a

modification of the contents at the address will have “global” visibility

• On the other hand, argument values are just copied in the “local memory” of a method; so a modification to a value within a method always remains local (changes contents of local memory)

22

Reversing an arrayclass Reverse { public static void main (String arg[]) { int size = 10; int somethingStrange[] = new

int[size];

Initialize (somethingStrange, size); PrintArray (somethingStrange, size); Reverse (somethingStrange, size); PrintArray (somethingStrange, size); }

23

Reversing an array public static void Initialize (int array[],

int size) { int i; array[0] = 1; for (i=1; i<size; i++) { array[i] = (array[i-1]*3) % 23; } }

24

Reversing an array public static void Reverse (int array[],

int size) { int head = 0, tail = size-1;

while (head < tail) { Swap (array, head, tail); head++; tail--; } }

25

Reversing an array public static void Swap (int array[], int

i, int j) { int temp;

temp = array[i]; array[i] = array[j]; array[j] = temp; }

26

Reversing an array public static void PrintArray (int

array[], int size) { int i;

for (i=0;i<size;i++) { System.out.println (array[i]); } }} // end class

27

Bubble sortclass BubbleSort { public static void main (String arg[]) { int size = 20; double array[] = new double[size];

Initialize (array, size); // not shown PrintArray (array, size); // not shown Sort (array, size); PrintArray (array, size); // not shown }

28

Bubble sort public static void Sort (double array[], int

size) { int i, j;

for (i=1;i<=size-1;i++) { for (j=0;j<=size-2;j++) { // better:

j<=size-i-1 CompareAndSwap (array, j, j+1); } // Invariant: maximum of sub-array is // in position size-i } }

29

Bubble sort public static void CompareAndSwap

(double array[], int p, int q) { double temp;

if (array[p] > array[q]) { temp = array[p]; array[p] = array[q]; array[q] = temp; } }} // end class (How many comparisons?)

30

Insertion sort public static void Sort (double array[], int

size) { int i, j;

for (i=1; i<size; i++) { for (j=0; array[i] > array[j]; j++); if (j < i) { Insert (array, i, j); } // Invariant: the first i+1 element // are sorted }

31

Insertion sort public static void Insert (double

array[], int oldpos, int newpos) { int i; double candidate = array[oldpos];

for (i=oldpos-1; i>=newpos; i--) { array[i+1] = array[i]; } array[i+1] = candidate; }

32

Insertion sort• How many comparisons?

– Need to consider worst case– What does the array look like in the worst

case?– What is the best case?

• Just the number of comparisons does not tell you the whole story– How many assignments do you execute?

33

Merging two sorted arrays• Suppose we have sorted the first m

and the remaining n-m elements of an array separately

• We need to merge these two sorted halves to get a complete sorted array

• Assume that everything is sorted in ascending order

34

Merging two sorted arrayspublic static void Merge (double array[], int start, int

m, int n) { // start would be 0 in this case double temp[] = new double[n-start]; int index = 0, index1, index2, i; for (index1=start, index2=m; (index1 < m) &&

(index2 < n);) { if (array[index1] < array[index2]) { temp[index] = array[index1]; index++; index1++; } else { temp[index] = array[index2]; index++; index2++; } } // continued in next slide

35

Merging two sorted arrays for(;index1<m;index1++,index++) { temp[index] = array[index1]; } for(;index2<n;index2++,index++) { temp[index] = array[index2]; } for (i=start;i<n;i++) { array[i] = temp[i-start]; }}

36

Merge sort• Recursively sort half of the array

separately and merge themclass MergeSort { public static void main (String arg[]) { int n = 20; double array[] = new double[n];

Initialize (array, n); // not shown Sort (array, 0, n-1); } // continued in next slide

37

Merge sort public static void Sort (double array[],

int start, int end) { if (start < end) { Sort (array, start, start+(end+1-

start)/2-1); Sort (array,

start+(end+1-start)/2, end); Merge (array, start, start+

(end+1-start)/2, end+1); } }} // end class

38

Merge sort• Running time? Let it be T(n) for an array of

size nT(n) = 2T(n/2) + cn for some constant c• Solution to this functional equation (or

recurrence) is the running time of merge sort

• T(n) = c’nlog2(n) for some constant c’ and large n– I can absorb the base of log in the constant

• Note that this is the worst case running time of merge sort– Much better than bubble sort and insertion sort

which had worst case running time quadratic in n

39

Prime numbers• Previously we checked for primality of

an integer n by dividing it by all integers up to √n

• We only need to divide by the primes up to √n

• Use an array to remember the primes seen so far

40

Prime numbersclass PrimeNumbers { // Find all primes up to n public static void main (String arg[]) { int n = 10000; // Assume n > 1 // Use Dusart’s bound (just using n wastes // too much of memory for large n) int maxNumPrimes =

(int)((n/Math.log(n))*(1+1.2762/Math.log(n))); int primes[] = new int[maxNumPrimes]; int numPrimesFound = 0; int i; // continued on next slide

41

Prime numbers for (i=2; i<=n; i++) { if (CheckPrimality (i, primes,

numPrimesFound)) { primes[numPrimesFound] = i; numPrimesFound++; } } PrintPrimes(primes,

numPrimesFound); } // end main // continued on next slide

42

Prime numbers public static boolean CheckPrimality (int n,

int primes[], int count) { int i; for (i=0; (i<count) && (primes[i] <=

Math.sqrt(n)); i++) { if ((n%primes[i])==0) { return false; } } return true; } // continued on next slide

43

Prime numbers public static void PrintPrimes (int primes[],

int count) { int i, j=0; for (i=0; i<count; i++) { System.out.print (primes[i] + “ ”); j++; if (j==10) { // print 10 primes per line System.out.print (“\n”); j=0; } } System.out.print (“\n”); }} // end class