Java Programming Tutorial
Exercises on Java Basics
You need to do these exercises by yourself. Please don’t ask me for solutions!
1. Writing Good Programs
The only way to learn programming is program, program and program. Learning programming is like learning cycling, swimming or any other sports. You can’t learn by watching or reading books. Start to program immediately. (On the other hands, to improve your programming, you need to read many books and study how the masters program.)
It is easy to write programs that work. It is much harder to write programs that not only work but also easy to maintain and understood by others – I call these good programs. In the real world, writing program is not meaningful. You have to write good programs, so that others can understand and maintain your programs.
Pratice problems taken from:
Pay particular attention to:
- Coding Style:
- Read “Java Code Convention” (@ http://www.oracle.com/technetwork/java/codeconvtoc-136057.html or google “Java Code Convention”).
- Follow the Java Naming Conventions for variables, methods, and classes STRICTLY. Use camel-case for names. Variable and method names begin with lowercase, while class names begin with uppercase. Use nouns for variables (e.g.,
radius
) and class names (e.g.,Circle
). Use verbs for methods (e.g.,getArea()
,isEmpty()
). - Use Meaningful Names: Do not use names like
a
,b
,c
,d
,x
,x1
,x2
, andx1688
. Avoid single-alphabet names likei
,j
,k
. They are easy to type, but usually meaningless. Use single-alphabet names only when their meaning is clear, e.g.,x
,y
,z
for co-ordinates andi
for array index. Use meaningful names likerow
andcol
(instead ofx
andy
,i
andj
,x1
andx2
),numStudents
,maxGrade
,size
, andupperbound
. Differentiate between singular and plural nouns (e.g., usebooks
for an array of books, andbook
for each item). - Use consistent indentation and coding style. Many IDEs (such as Eclipse/NetBeans) can re-format your source codes with a click.
- Program Documentation: Comment! Comment! and more Comment!
2. Exercises on Flow Controls
2.1 Exercises on Conditional (Decision)
Exercise CheckPassFail (if-else): Write a program called CheckPassFail
which prints “PASS
” if the int
variable “mark
” is more than or equal to 50
; or prints “FAIL
” otherwise. The program shall always print “DONE
” before exiting.
Hints:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<span class="color-comment">/* * Trying if-else statement. */</span> public class <strong>CheckPassFail</strong> { <span class="color-comment">// Save as "CheckPassFail.java"</span> public static void main(String[] args) { <span class="color-comment">// Program entry point</span> int mark = 49; <span class="color-comment">// Set the value of "mark" here!</span> System.out.println("The mark is " + mark); if ( ...... ) { System.out.println( ...... ); } else { System.out.println( ...... ); } System.out.println( ...... ); } } |
Take note of the source-code indentation!!! Whenever you open a block with '{'
, indent all the statements inside the block by 3 or 4 spaces. When the block ends, un-indent the closing '}'
to align with the opening statement.
Exercise CheckOddEven (if-else): Write a program called CheckOddEven
which prints “Odd Number
” if the int
variable “number
” is odd, or “Even Number
” otherwise. The program shall always print “BYE!
” before exiting.
Hints: n
is an even number if (n % 2)
is 0
; otherwise, it is an odd number.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<span class="color-comment">/* * Trying if-else statement and modulus (%) operator. */</span> public class <strong>CheckOddEven</strong> { <span class="color-comment">// Save as "CheckOddEven.java"</span> public static void main(String[] args) { <span class="color-comment">// Program entry point</span> int number = 49; <span class="color-comment">// Set the value of "number" here!</span> System.out.println("The number is " + number); if ( ...... ) { System.out.println( ...... ); } else { System.out.println( ...... ); } System.out.println( ...... ); } } |
Exercise PrintNumberInWord (nested-if, switch-case): Write a program called PrintNumberInWord
which prints “ONE
“, “TWO
“,… , “NINE
“, “OTHER
” if the int
variable “number
” is 1, 2,… , 9, or other, respectively. Use (a) a “nested-if” statement; (b) a “switch-case” statement.
Hints:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<span class="color-comment">/* * Trying nested-if and switch-case statements. */</span> public class <strong>PrintNumberInWord</strong> { <span class="color-comment">// Save as "PrintNumberInWord.java"</span> public static void main(String[] args) { int number = 5; <span class="color-comment">// Set the value of "number" here!</span> <span class="color-comment">// Using nested-if</span> if (number == 1) { System.out.println( ...... ); } else if ( ...... ) { ...... } else if ( ...... ) { ...... ...... } else { ...... } <span class="color-comment">// Using switch-case</span> switch(number) { case 1: System.out.println( ...... ); break; <span class="color-comment">// Don't forget "break"</span> case 2: System.out.println( ...... ); break; ...... ...... default: System.out.println( ...... ); } } } |
Exercise PrintDayInWord (nested-if, switch-case): Write a program called PrintDayInWord
which prints “Sunday
”, “Monday
”, … “Saturday
” if the int
variable “day
” is 0, 1, …, 6, respectively. Otherwise, it shall print “Not a valid day
”. Use (a) a “nested-if” statement; (b) a “switch-case” statement.
2.2 Exercises on Loop (Iteration)
Exercise SumAndAverage (Loop): Write a program called SumAndAverage
to produce the sum of 1, 2, 3, …, to 100. Also compute and display the average. The output shall look like:
1 2 |
The sum is 5050 The average is 50.5 |
Hints:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<span class="color-comment">/* * Compute the sum and average of running numbers from a lowerbound to an upperbound using loop. */</span> public class <strong>SumAndAverage</strong> { <span class="color-comment">// Save as "SumAndAverage.java"</span> public static void main (String[] args) { int sum = 0; <span class="color-comment">// Store the accumulated sum, init to 0</span> double average; <span class="color-comment">// average in double</span> int lowerbound = 1; <span class="color-comment">// The lowerbound to sum</span> int upperbound = 100; <span class="color-comment">// The upperbound to sum</span> <span class="color-comment">// Use a for-loop to sum from lowerbound to upperbound</span> for (int number = lowerbound; number <= upperbound; ++number) { sum += number; <span class="color-comment">// same as "sum = sum + number"</span> } <span class="color-comment">// Compute average in double. Beware that int/int produces int.</span> ...... <span class="color-comment">// Print sum and average.</span> ...... } } |
Try:
- Modify the program to use a “while-do” loop instead of “for” loop.
123456int number = lowerbound;int sum = 0;while (number <= upperbound) {sum += number;++number;} - Modify the program to use a “do-while” loop.
123456int number = lowerbound;int sum = 0;do {sum += number;++number;} while (number <= upperbound); - What is the difference between “for” and “while-do” loops? What is the difference between “while-do” and “do-while” loops?
- Modify the program to sum from 111 to 8899, and compute the average. Introduce an
int
variable calledcount
to count the numbers in the specified range.
12345int count = 0; <span class="color-comment">// count the number within the range, init to 0</span>for ( ...; ...; ... ) {......++count;} - Modify the program to sum only the odd numbers from 1 to 100, and compute the average. (HINTS:
n
is an odd number ifn % 2
is not0
.) - Modify the program to sum those numbers from 1 to 100 that is divisible by 7, and compute the average.
- Modify the program to find the “sum of the squares” of all the numbers from 1 to 100, i.e. 1*1 + 2*2 + 3*3 + … + 100*100.
Exercise Product1ToN (Loop): Write a program called Product1ToN
to compute the product of integers 1 to 10 (i.e., 1×2×3×…×10). Try computing the product from 1 to 11, 1 to 12, 1 to 13 and 1 to 14. Write down the product obtained and explain the results.
Hints: Declare an int
variable called product
(to accumulate the product) and initialize to 1.
Try: Compute the product from 1 to 11, 1 to 12, 1 to 13 and 1 to 14. Write down the product obtained and decide if the results are correct.
Try: Repeat the above, but use long
to store the product. Compare the products obtained.
Hints: Product of 1 to 13 (=6227020800) is outside the range of int [-2147483648, 2147483647], but within the range of long
. Take note that computer programs may not produce the correct answer even though everything seems correct!
Exercise HarmonicSum (Loop): Write a program called HarmonicSum
to compute the sum of a harmonic series, as shown below, where n
=50000. The program shall compute the sum from left-to-right as well as from the right-to-left. Obtain the difference between these two sums and explain the difference. Which sum is more accurate?
Hints:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<span class="color-comment">/* * Compute the sum of harmonics series from left-to-right and right-to-left. */</span> public class <strong>HarmonicSum</strong> { <span class="color-comment">// Save as "HarmonicSum.java"</span> public static void main (String[] args) { int maxDenominator = 50000; <span class="color-comment">// Use a more meaningful name instead of n</span> double sumL2R = 0.0; <span class="color-comment">// sum from left-to-right</span> double sumR2L = 0.0; <span class="color-comment">// sum from right-to-left</span> <span class="color-comment">// for-loop for summing from left-to-right</span> for (int denominator = 1; denominator <= maxDenominator; ++denominator) { ...... <span class="color-comment">// Beware that int/int gives int, e.g., 1/2 gives 0.</span> } System.out.println("The sum from left-to-right is: " + sumL2R); <span class="color-comment">// for-loop for summing from right-to-left</span> ...... <span class="color-comment">// Find the difference and display</span> ...... } } |
Exercise ComputePI (Loop & Condition): Write a program called ComputePI
to compute the value of π, using the following series expansion. You have to decide on the termination criterion used in the computation (such as the number of terms used or the magnitude of an additional term). Is this series suitable for computing π?
JDK maintains the value of π in a
double
constant called Math.PI
. Compare the values obtained and the Math.PI
, in percents of Math.PI
.
Hints: Add to sum if the denominator modulus 4 is 1, and subtract from sum if it is 3.
1 2 3 4 5 6 7 8 9 10 11 |
double sum = 0.0; int maxDenominator = 10000000; for (int denominator = 1; denominator <= maxDenominator; denominator += 2) { <span class="color-comment">// 1, 3, 5, 7,...</span> if (denominator % 4 == 1) { sum += ......; } else if (denominator % 4 == 3) { sum -= ......; } else { <span class="color-comment">// remainder of 0 or 2</span> System.out.println("The computer has gone crazy?!"); } } |
Try maxDenominator
of 100000, 1000000 and comment on the value of PI computed.
Alternatively, you can use the term number as the loop index:
1 2 3 4 5 6 7 8 9 |
int maxTerm = 25000; <span class="color-comment">// number of terms used in computation</span> int sum = 0.0; for (int term = 1; term <= maxTerm; term++) { <span class="color-comment">// term = 1,2,3,... ,maxTerm</span> if (term % 2 == 1) { <span class="color-comment">// odd term number: add</span> sum += 1.0/(term*2-1); } else { <span class="color-comment">// even term number: subtract</span> ...... } } |
Exercise CozaLozaWoza (Loop & Condition): Write a program called CozaLozaWoza
which prints the numbers 1 to 110, 11 numbers per line. The program shall print “Coza” in place of the numbers which are multiples of 3, “Loza” for multiples of 5, “Woza” for multiples of 7, “CozaLoza” for multiples of 3 and 5, and so on. The output shall look like:
1 2 3 4 |
1 2 Coza 4 Loza Coza Woza 8 Coza Loza 11 Coza 13 Woza CozaLoza 16 17 Coza 19 Loza CozaWoza 22 23 Coza Loza 26 Coza Woza 29 CozaLoza 31 32 Coza ...... |
Hints:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class <strong>CozaLozaWoza</strong> { <span class="color-comment">// Save as "CozaLozaWoza.java"</span> public static void main(String[] args) { int lowerbound = 1, upperbound = 110; for (int number = lowerbound; number <= upperbound; ++number) { <span class="color-comment">// Print "Coza" if number is divisible by 3</span> if ( ...... ) { System.out.print("Coza"); } <span class="color-comment">// Print "Loza" if number is divisible by 5</span> if ( ...... ) { System.out.print(.....); } <span class="color-comment">// Print "Woza" if number is divisible by 7</span> ...... <span class="color-comment">// Print the number if it is not divisible by 3, 5 and 7 (i.e., it has not been processed above)</span> if ( ...... ) { ...... } <span class="color-comment">// After processing the number, print a newline if number is divisible by 11; // else print a space</span> if ( ...... ) { System.out.println(); <span class="color-comment">// print newline</span> } else { System.out.print( ...... ); <span class="color-comment">// print a space</span> } } } } |
A better solution is to use a boolean
flag to keep track of whether the number has been processed, as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
int lowerbound = 1, upperbound = 110; <span class="color-new">boolean printed;</span> for (int number = lowerbound; number <= upperbound; ++number) { <span class="color-new">printed = false;</span> <span class="color-comment">// init before processing each number</span> <span class="color-comment">// Print "Coza" if number is divisible by 3</span> if ( ...... ) { System.out.print( ...... ); <span class="color-new">printed = true;</span> <span class="color-comment">// processed!</span> } <span class="color-comment">// Print "Loza" if number is divisible by 5</span> if ( ...... ) { System.out.print( ..... ); <span class="color-new">printed = true;</span> <span class="color-comment">// processed</span>! } <span class="color-comment">// Print "Woza" if number is divisible by 7</span> ...... <span class="color-comment">// Print the number if it has not been processed</span> if (<span class="color-new">!printed</span>) { ...... } <span class="color-comment">// After processing the number, print a newline if it is divisible by 11; // else, print a space</span> ...... } |
Exercise Fibonacci (Loop): Write a program called Fibonacci
to display the first 20 Fibonacci numbers F(n)
, where F(n)=F(n–1)+F(n–2)
and F(1)=F(2)=1
. Also compute their average. The output shall look like:
1 2 3 |
The first 20 Fibonacci numbers are: 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 The average is 885.5 |
Hints:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<span class="color-comment">/* * Print first 20 Fibonacci numbers and their average */</span> public class <strong>Fibonacci</strong> { public static void main (String args[]) { int n = 3; <span class="color-comment">// the index n for F(n), starting from n=3</span> int fn; <span class="color-comment">// F(n) to be computed</span> int fnMinus1 = 1; <span class="color-comment">// F(n-1), init to F(2)</span> int fnMinus2 = 1; <span class="color-comment">// F(n-2), init to F(1)</span> int nMax = 20; <span class="color-comment">// maximum n, inclusive</span> int sum = fnMinus1 + fnMinus2; <span class="color-comment">// Need sum to compute average</span> double average; System.out.println("The first " + nMax + " Fibonacci numbers are:"); ...... while (n <= nMax) { <span class="color-comment">// n starts from 3</span> <span class="color-comment">// Compute F(n), print it and add to sum</span> ...... <span class="color-comment">// Increment the index n and shift the numbers for the next iteration</span> ++n; fnMinus2 = fnMinus1; fnMinus1 = fn; } <span class="color-comment">// Compute and display the average (=sum/nMax). // Beware that int/int give int.</span> ...... } } |
Exercise Tribonacci (Loop): Tribonacci numbers are a sequence of numbers T(n)
similar to Fibonacci numbers, except that a number is formed by adding the three previous numbers, i.e., T(n)=T(n-1)+T(n-2)+T(n-3)
, T(1)=T(2)=1
, and T(3)=2
. Write a program called Tribonacci
to produce the first twenty Tribonacci numbers.
Exercise ExtractDigits (Loop): Write a program called ExtractDigits
to extract each digit from an int
, in the reverse order. For example, if the int
is 15423, the output shall be “3 2 4 5 1”, with a space separating the digits.
Hints: Use n % 10
to extract the least-significant digit; and n = n / 10
to discard the least-significant digit.
1 2 3 4 5 6 7 |
int n = .......; while (n > 0) { int digit = n % 10; <span class="color-comment">// Extract the least-significant digit</span> ...... ...... n = n / 10; <span class="color-comment">// Drop the least-significant digit and repeat the loop</span> } |
2.3 Exercises on Nested-Loop
Exercise SquareBoard (nested-loop): Write a program called SquareBoard
that displays the following n×n
(n=5
) pattern using two nested for-loops.
1 2 3 4 5 |
# # # # # # # # # # # # # # # # # # # # # # # # # |
Your program should use only two output statements, one EACH of the followings:
1 2 |
System.out.print("# "); <span class="color-comment">// print # and a space, without newline</span> System.out.println(); <span class="color-comment">// print a newline</span> |
Hints:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<span class="color-comment">/* * Print square pattern using nested-loop */</span> public class <strong>SquareBoard</strong> { <span class="color-comment">// Save as "SquareBoard.java"</span> public static void main (String[] args) { int size = 5; <span class="color-comment">// size of the board</span> for (int row = 1; row <= size; ++row) { <span class="color-comment">// Use row and col, NOT i and j, or x and y</span> for (int col = 1; ......; ......) { ...... } ...... } } } |
Notes: The code pattern for printing 2D patterns using nested loop is:
1 2 3 4 5 6 7 8 9 10 11 |
<span class="color-comment">// Outer loop to print each of the rows</span> for (int row = 1; row <= size; row++) { <span class="color-comment">// Inner loop to print each of the columns of one particular row</span> for (int col = 1; col <= size; col++) { System.out.print( ...... ) ...... } <span class="color-comment">// Print a newline after all the columns</span> System.out.println(); } <span class="color-comment">// You should name the variables row and col, NOT i and j or x and y!!!</span> |
Exercise CheckerBoard (nested-loop): Write a program called CheckerBoard
that displays the following n×n
(n=7
) checkerboard pattern using two nested for-loops.
1 2 3 4 5 6 7 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
Your program should use only three output statements, one EACH of the followings:
1 2 3 |
System.out.print("# "); <span class="color-comment">// print # and a space, without newline</span> System.out.print(" "); <span class="color-comment">// print a space, without newline</span> System.out.println(); <span class="color-comment">// print a newline</span> |
Hints:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<span class="color-comment">/* * Print checkerboard pattern using nested-loop */</span> public class <strong>CheckerBoard</strong> { <span class="color-comment">// Save as "CheckerBoard.java"</span> public static void main (String[] args) { int size = 7; <span class="color-comment">// size of the board</span> for (int row = 1; ......; ......) { <span class="color-comment">// Use modulus 2 to find alternate lines</span> if ((row % 2) == 0) { <span class="color-comment">// row 2, 4, 6, 8</span> ...... } for (int col = 1; ......; ......) { ...... } ...... } } } |
Exercise TimeTable (nested-loop): Write a program called TimeTable
to produce the multiplication table of 1 to 9 as shown using two nested for-loops:
1 2 3 4 5 6 7 8 9 10 11 |
* | 1 2 3 4 5 6 7 8 9 ------------------------------- 1 | 1 2 3 4 5 6 7 8 9 2 | 2 4 6 8 10 12 14 16 18 3 | 3 6 9 12 15 18 21 24 27 4 | 4 8 12 16 20 24 28 32 36 5 | 5 10 15 20 25 30 35 40 45 6 | 6 12 18 24 30 36 42 48 54 7 | 7 14 21 28 35 42 49 56 63 8 | 8 16 24 32 40 48 56 64 72 9 | 9 18 27 36 45 54 63 72 81 |
Modify the program to print the multiplication table of 1 to 12. (Hints: use printf()
to format the numbers.)
Exercise PrintPattern (nested-loop): Print each of the followings patterns using nested loops.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # (a) (b) (c) (d) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # (e) (f) (g) (h) (i) |
Hints: On the main diagonal, row = col
. On the opposite diagonal, row + col = size + 1
, where row
and col
begin from 1.
3. Debugging/Tracing Programs using a Graphic Debugger
Exercise (Using a graphic debugger): The following program computes and prints the factorial of n
(=1*2*3*...*n
). The program, however, has a logical error and produce a wrong answer for n=20
(“The Factorial of 20 is -2102132736” – negative?!). Use the graphic debugger of Eclipse/NetBeans to debug the program by single-step through the program and tabulating the values of i
and factorial
at the statement marked by (*
).
You should try out debugging features such as “Breakpoint”, “Step Over”, “Watch variables”, “Run-to-Line”, “Resume”, “Terminate”, among others. (Read “Eclipse for Java” or “NetBeans for Java” for details).
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class Factorial { <span class="color-comment">// Print factorial of n</span> public static void main(String[] args) { <span class="color-comment">// Set an initital breakpoint at this statement</span> int n = 20; int factorial = 1; <span class="color-comment">// n! = 1*2*3...*n</span> for (int i = 1; i <= n; i++) { factorial = factorial * i; } System.out.println("The Factorial of " + n + " is " + factorial); } } |
4. Exercises on Keyboard and File Input
Exercise KeyboardScanner (Keyboard Input): Write a program called KeyboardScanner
to prompt user for an int
, a double
, and a String
. The output shall look like (the inputs are shown in bold):
1 2 3 4 |
Enter an integer: <strong>12</strong> Enter a floating point number: <strong>33.44</strong> Enter your name: <strong>Peter</strong> Hi! Peter, the sum of 12 and 33.44 is 45.44 |
Hints:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import java.util.Scanner; <span class="color-comment">// needed to use Scanner for input</span> public class <strong>KeyboardScanner</strong> { public static void main(String[] args) { int num1; double num2; String name; double sum; <span class="color-comment">// Setup a Scanner called in to scan the keyboard (System.in)</span> Scanner in = new Scanner(System.in); System.out.print("Enter an integer: "); num1 = in.nextInt(); <span class="color-comment">// use nextInt() to read int</span> System.out.print("Enter a floating point number: "); num2 = in.nextDouble(); <span class="color-comment">// use nextDouble() to read double</span> System.out.print("Enter your name: "); name = in.next(); <span class="color-comment">// use next() to read String</span> <span class="color-comment">// Display</span> ...... <span class="color-comment">// Close the input stream</span> in.close(); } } |
Exercise FileScanner (File Input): Write a program called FileScanner
to read an int
, a double
, and a String
form a text file called “in.txt
“, and produce the following output:
1 2 3 4 |
The integer read is 12 The floating point number read is 33.44 The String read is "Peter" Hi! Peter, the sum of 12 and 33.44 is 45.44 |
You need to create a text file called “in.txt
” (in Eclipse, right-click on the “project” ⇒ “New” ⇒ “File”) with the following contents:
1 2 3 |
12 33.44 Peter |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import java.util.Scanner; <span class="color-comment">// Needed to use Scanner for input</span> import java.io.File; <span class="color-comment">// Needed to use File</span> import java.io.FileNotFoundException; <span class="color-comment">// Needed for file operation</span> public class <strong>FileScanner</strong> { public static void main(String[] args) throws FileNotFoundException { <span class="color-comment">// Needed for file operation</span> int num1; double num2; String name; double sum; <span class="color-comment">// Setup a Scanner to read from a text file</span> Scanner in = new Scanner(new File("in.txt")); num1 = in.nextInt(); <span class="color-comment">// use nextInt() to read int</span> num2 = in.nextDouble(); <span class="color-comment">// use nextDouble() to read double</span> name = in.next(); <span class="color-comment">// use next() to read String</span> <span class="color-comment">// Display</span> ...... in.close(); } } |
Ignore the Exception Handling codes for the time being. They will be covered in due course.
Exercise CircleComputation (User Input): Write a program called CircleComputation
, which prompts user for a radius
(in double
) and compute the area
and circumference
of the circle rounded to 2 decimal places. The output shall look like:
1 2 3 |
Enter the radius: <strong>1.2</strong> The area is: 4.52 The circumference is: 7.53 |
Hints: π is kept in a constant called Math.PI
.
Exercise CircleComputation (User Input & Sentinel Value): Modify the above exercise. The program shall repeatedly prompt for the radius
, until the user enters -1
. For example,
1 2 3 4 5 6 7 8 9 |
Enter the radius: 1.2 The area is: 4.52 The circumference is: 7.53 Enter the radius: 2.1 The area is: 13.85 The circumference is: 13.19 Enter the radius: -1 |
Hints: To repeat until input is -1 (called sentinel value), use the following pattern:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
int number; <span class="color-comment">// Read first input</span> System.out.print("Enter a positive integer or -1 to exit: "); number = in.nextInt(); while (number != -1) { <span class="color-comment">// Continue only if input is not -1</span> <span class="color-comment">// Process the number</span> ...... ...... <span class="color-comment">// Read next input (Take note that you need to repeat these statements)</span> System.out.print("Enter a positive integer or -1 to exit: "); number = in.nextInt(); } |
5. Exercises on String and char Operations
Exercise ReverseString: Write a program called ReverseString
, which prompts user for a String
, and prints the reverse of the String
. The output shall look like:
1 2 |
Enter a String: <strong>abcdef</strong> The reverse of the String "abcdef" is "fedcba". |
Hints:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import java.util.Scanner; public class <strong>ReverseString</strong> { public static void main(String[] args) { String inStr; <span class="color-comment">// input String</span> int inStrLen; <span class="color-comment">// length of the input String</span> Scanner in = new Scanner(System.in); System.out.print("Enter a String: "); inStr = in.next(); <span class="color-comment">// use next() to read a String</span> inStrLen = inStr.length(); <span class="color-comment">// Use inStr.charAt(index) in a loop to extract character at "index" from inStr // The String's index begins at 0 from the left.</span> for (int i = inStrLen - 1; i >= 0; --i) { <span class="color-comment">// Process the String from the right</span> ...... } } } |
For a String
called inStr
, you can use inStr.length()
to get the length of the String
; and inStr.charAt(index)
to retrieve the char
at the index
position, where index
begins with 0.
Exercise CheckVowelsDigits: Write a program called CheckVowelsDigits
, which prompts the user for a String
, counts the number of vowels (a, e, i, o, u, A, E, I, O, U) and digits (0-9) contained in the string, and prints the counts and the percentages (with 2 decimal digits). For example,
1 2 3 |
Enter a String: <strong>testing12345</strong> Number of vowels: 2 (16.67%) Number of digits: 5 (41.67%) |
Hints:
- To check if a
char c
is a digit, you can useboolean
expression(c >= '0' && c <= '9')
; or use built-in
boolean
functionCharacter.isDigit(c)
. - You could use
in.next().toLowerCase()
to convert the inputString
to lowercase reduce the number of cases. - To print a
%
usingprintf()
, you need to use%%
. This is because%
has a special meaning inprintf()
, e.g.,%d
and%f
.
Exercise PhoneKeyPad: On your phone keypad, the alphabets are mapped to digits as follows: ABC(2)
, DEF(3)
, GHI(4)
, JKL(5)
, MNO(6)
, PQRS(7)
, TUV(8)
, WXYZ(9)
. Write a program called PhoneKeyPad
, which prompts user for a String
(case insensitive), and converts to a sequence of keypad digits. Use a nested-if (or switch-case) in this exercise.
Hints:
- You can use
in.next().toLowerCase()
to read aString
and convert it to lowercase to reduce your cases. - In
switch
, you can handle multiple cases, e.g.,
12345678switch (inChar) { <span class="color-comment">// switch on a char</span>case 'a': case 'b': case 'c':System.out.print(2); break;case 'd': case 'e': case 'f':......default:......}
Exercise TestPalindromicWord: A word that reads the same backward as forward is called a palindrome, e.g., “mom”, “dad”, “racecar”, “madam”, and “Radar” (case-insensitive). Write a program called TestPalindromicWord
, that prompts user for a word and prints “"xxx" is|is not a palindrome
“.
A phrase that reads the same backward as forward is also called a palindrome, e.g., “Madam, I’m Adam”, “A man, a plan, a canal – Panama!” (ignoring punctuation and capitalization). Modify your program (called TestPalindromicPhrase
) to test palindromic phrase.
Hints: Maintain two indexes, forwardIndex
and backwardIndex
, used to scan the phrase forward and backward. You can check if a char c
is a letter either using built-in boolean
functionCharacter.isLetter(c)
; or boolean
expression (c >= 'a' && c <= 'z')
. Skip the index if it does not contain a letter.
1 2 3 4 |
int fIdx = 0, bIdx = strLen -1; while (fIdx < bIdx) { ...... } |
Exercise Bin2Dec: Write a program called Bin2Dec
to convert an input binary string into its equivalent decimal number. Your output shall look like:
1 2 3 4 5 |
Enter a Binary string: <strong>1011</strong> The equivalent decimal number for binary "1011" is: 11 Enter a Binary string: <strong>1234</strong> error: invalid binary string "1234" |
Hints: For a n
-bit binary number bn-1bn-2...b1b0, bi∈{0,1}
, the equivalent decimal number is bn-1×2n-1+bn-2×2n-2+ ...+b1×21+b0×20
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import java.util.Scanner; public class Bin2Dec { public static void main(String[] args) { String binStr; <span class="color-comment"> // The Input binary string</span> int binStrLen; <span class="color-comment"> // Length of the input string</span> int dec = 0; <span class="color-comment"> // The equivalent decimal number, accumulate from 0</span> ...... <span class="color-comment"> // Read input into binStr and compute binStrLen</span> ...... <span class="color-comment"> // Convert the binary string to decimal, starting from the most-significant digit (left)</span> for (int pos = 0; pos < binStrLen; ++pos) { int order = binStrLen - 1 - pos; char binChar = binStr.charAt(pos); <span class="color-comment"> // 3 cases: '1' (add to dec), '0' (do nothing), others (error)</span> if (binChar == '1') { ...... } else if (binChar != '0') { System.out.println("error: invalid binary string \"" + binStr + "\""); System.exit(1); } <span class="color-comment">// else for '0' - do nothing</span> } <span class="color-comment"> // Print result</span> ...... } } |
1 2 3 4 5 6 |
binStr : 1 0 1 1 1 0 0 1 charAt(pos) : 0 1 2 3 4 5 6 7 (pos from the left) Math.pow(2, order) : 7 6 5 4 3 2 1 0 (order from the right) binStr.length() = 8 pos + order = binStr.length() - 1 |
You can use JDK method Math.pow(x, y)
to compute the x
raises to the power of y
. This method takes two double
s as argument and returns a double
. You have to cast the result back toint
.
To convert a char c
(of digit '0'
to '9'
) to int
(0
to 9
), simply subtract by char
'0'
, e.g., '5'-'0'
gives int
5
.
NOTES: You can use Scanner
‘s nextInt(int radix)
to read an int
in the desired radix
. Try reading a binary number (radix of 2) and print its decimal equivalent.
Exercise Hex2Dec: Write a program called Hex2Dec
to convert an input hexadecimal string into its equivalent decimal number. Your output shall look like:
1 2 3 4 5 |
Enter a Hexadecimal string: <strong>1a</strong> The equivalent decimal number for hexadecimal "1a" is: 26 Enter a Hexadecimal string: <strong>1y3</strong> error: invalid hexadecimal string "1y3" |
Hints:
For a n
-digit hexadecimal number hn-1hn-2...h1h0, hi∈{0,…,9,A,…,F}
, the equivalent decimal number is hn-1×16n-1+hn-2×16n-2+ ...+h1×161+h0×160
.
You need to transform char
'0'
to '9'
to int
0-9
; and char
'a'
to 'f'
(or 'A'
to 'F'
) to int
10-15
. However, you do not need a big nested-if statement of 16 cases (or 22 considering the upper and lower letters). Extract the individual character from the hexadecimal string, says c
. If char c
is between '0'
to '9'
, you can get the integer offset via c-'0'
. If c
is between 'a'
to 'f'
or 'A'
to 'F'
, the integer offset is c-'a'+10
or c-'A'+10
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
String hexStr; char hexChar; ...... hexChar = hexStr.charAt(pos); ...... <span class="color-comment">// 23 cases: '0'-'9', 'a'-'f', 'A'-'F', others (error)</span> if (hexChar >= '0' && hexChar <= '9') { ... (hexChar-'0') ... ... } else if (hexChar >= 'a' && hexChar <= 'f') { <span class="color-comment">// lowercase</span> ... (hexChar-'a'+10) ... ... } else if (hexChar >= 'A' && hexChar <= 'F') { <span class="color-comment">// uppercase (use in.next().toLowerCase() to eliminate this)</span> ... (hexChar-'A'+10) ... ... } else { System.out.println("error: invalid hexadecimal string"); System.exit(1); <span class="color-comment">// quit the program</span> } |
Exercise Oct2Dec: Write a program called Oct2Dec
to convert an input Octal string into its equivalent decimal number.
Exercise Radix2Dec: Write a program called Radix2Dec
to convert an input string of any radix into its equivalent decimal number.
1 2 3 |
Enter the radix: <strong>16</strong> Enter the string: <strong>1a</strong> The equivalent decimal number "1a" is: 26 |
6. Exercises on Array
Exercise GradesAverage (Array): Write a program called GradesAverage
, which prompts user for the number of students, reads it from the keyboard, and saves it in an int
variable called numStudents
. It then prompts user for the grades of each of the students and saves them in an int
array called grades
. Your program shall check that the grade
is between 0
and 100
. A sample session is as follow:
1 2 3 4 5 6 7 |
Enter the number of students: <strong>3</strong> Enter the grade for student 1: <strong>55</strong> Enter the grade for student 2: <strong>108</strong> Invalid grade, try again... Enter the grade for student 2: <strong>56</strong> Enter the grade for student 3: <strong>57</strong> The average is: 56.0 |
Exercise Hex2Bin (Array for Table Lookup): Write a program called Hex2Bin
to convert a hexadecimal string into its equivalent binary string. The output shall look like:
1 2 |
Enter a Hexadecimal string: <strong>1abc</strong> The equivalent binary for hexadecimal "1abc" is: 0001 1010 1011 1100 |
Hints: Use an array of 16 binary String
s corresponding to hexadecimal number '0'
to 'F'
(or 'f'
), as follows:
1 2 3 4 |
String[] hexBits = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"}; |
7. Exercises on Method
Exercise (Method): Write a boolean
method called isOdd()
in a class called OddTest
, which takes an int
as input and returns true
if the it is odd. The signature of the method is as follows:
1 |
public static boolean isOdd(int number) |
Also write the main()
method that prompts user for a number
, and prints “ODD” or “EVEN”. You should test for negative input.
Exercise (Method): Write a boolean
method called hasEight()
, which takes an int
as input and returns true
if the number contains the digit 8
(e.g., 18
, 808
). The signature of the method is as follows:
1 |
public static boolean hasEight(int number) |
Write a program called MagicSum
, which prompts user for numbers, and produce the sum of numbers containing the digit 8
. Your program should use the above methods. A sample output of the program is as follows:
1 2 3 4 5 6 7 |
Enter a positive integer or -1 to exit: 1 Enter a positive integer or -1 to exit: 2 Enter a positive integer or -1 to exit: 3 Enter a positive integer or -1 to exit: 8 Enter a positive integer or -1 to exit: 88 Enter a positive integer or -1 to exit: -1 The magic sum is: 96 |
Hints: To repeat until input is -1
(called sentinel value):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
int number; int sentinel = -1; <span class="color-comment">// Read first input</span> System.out.print("Enter a positive integer or -1 to exit: "); number = in.nextInt(); while (number != sentinel) { <span class="color-comment">// Read until input is -1</span> ...... <span class="color-comment">// Read next input (Take note that you need to repeat these codes!)</span> System.out.print("Enter a positive integer or -1 to exit: "); number = in.nextInt(); } |
Hints: You can either convert the int
to String
and use the String
‘s charAt()
to inspect each char
; or repeatably use n%10
and n=n/10
to extract each digit (in int
).
Exercise (Array and Method): Write a method called printArray()
, which takes an int
array and print its contents in the form of
{a1, a2, ..., an}
. Take note that there is no comma after the last element. The method’s signature is as follows:
1 |
public static void printArray(int[] array) |
Also write a test driver to test this method (you should test on empty array, one-element array, and n-element array).
How to handle double[]
or float[]
? You need to write another version for double[]
, e.g.,
1 2 |
public static void printArray(double[] array) public static void printArray(float[] array) |
The above is known as method overloading, where the same method name can have many versions, differentiated by its parameter list.
Exercise (Array and Method): Write a method called arrayToString()
, which takes an int
array and return a String
in the form of
{a1, a2, ..., an}
. Take note that there is no comma after the last element. The method’s signature is as follows:
1 |
public static String arrayToString(int[] array) |
Also write a test driver to test this method (you should test on empty array, one-element array, and n-element array).
Notes: This is similar to the built-in function Arrays.toString()
. You could study its source code.
Exercise (Array and Method): Write a boolean
method called contains()
, which takes an array of int
and an int
; and returns true
if the array contains the given int
. The method’s signature is as follows:
1 |
public static boolean contains(int[] array, int key) |
Also write a test driver to test this method.
Exercise (Array and Method): Write a method called search()
, which takes an array of int
and an int
; and returns the array index if the array contains the given int
; or -1
otherwise. The method’s signature is as follows:
1 |
public static int search(int[] array, int key) |
Also write a test driver to test this method.
Exercise (Array and Method): Write a boolean
method called equals()
, which takes two arrays of int
and returns true
if the two arrays are exactly the same (i.e., same length and same contents). The method’s signature is as follows:
1 |
public static boolean equals(int[] array1, int[] array2) |
Also write a test driver to test this method.
Exercise (Array and Method): Write a boolean
method called copyOf()
, which an int
Array and returns a copy of the given array. The method’s signature is as follows:
1 |
public static int[] copyOf(int[] array) |
Also write a test driver to test this method.
Write another version for copyOf()
which takes a second parameter to specify the length of the new array. You should truncate or pad with zero so that the new array has the required length.
1 |
public static int[] copyOf(int[] array, int newLength) |
NOTES: This is similar to the built-in function Arrays.copyOf()
.
Exercise (Array and Method): Write a method called reverse()
, which takes an array of int
and reverse its contents. For example, the reverse of {1,2,3,4}
is {4,3,2,1}
. The method’s signature is as follows:
1 |
public static void reverse(int[] array) |
Take note that the array passed into the method can be modified by the method (this is called “pass by reference“). On the other hand, primitives passed into a method cannot be modified. This is because a clone is created and passed into the method instead of the original copy (this is called “pass by value“).
Also write a test driver to test this method.
Hint: You need to use a temp location (an int
) to swap the first element with the last element, and so on.
Exercise (Array and Method): Write a method called swap()
, which takes two arrays of int
and swap their contents if they have the same length. It shall return true
if the contents are successfully swapped. The method’s signature is as follows:
1 |
public static boolean swap(int[] array1, int[] array2) |
Also write a test driver to test this method.
Hint: You need to use a temp location (an int
) to swap the corresponding elements of the two arrays.
Exercise GradesStatistics (Method): Write a program called GradesStatistics
, which reads in n
grades (of int
between 0
and 100
, inclusive) and displays the average, minimum,maximum, median and standard deviation. Display the floating-point values upto 2 decimal places. Your output shall look like:
1 2 3 4 5 6 7 8 9 10 11 |
Enter the number of students: <strong>4</strong> Enter the grade for student 1: <strong>50</strong> Enter the grade for student 2: <strong>51</strong> Enter the grade for student 3: <strong>56</strong> Enter the grade for student 4: <strong>53</strong> {50,51,56,53} The average is: 52.50 The median is: 52.00 The minimum is: 50 The maximum is: 56 The standard deviation is: 2.29 |
The formula for calculating standard deviation is:
Hints:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
public class <strong>GradesStatistics</strong> { public static int[] grades; <span class="color-comment">// Declare an int[], to be allocated later. // This array is accessible by all the methods.</span> public static void main(String[] args) { readGrades(); <span class="color-comment">// Read and save the inputs in int[] grades</span> printArray(grades); System.out.println("The average is " + average(grades)); System.out.println("The median is " + median(grades)); System.out.println("The minimum is " + min(grades)); System.out.println("The maximum is " + max(grades)); System.out.println("The standard deviation is " + stdDev(grades)); } <span class="color-comment">// Prompt user for the number of students and allocate the global "grades" array. // Then, prompt user for grade, check for valid grade, and store in "grades". </span> public static void readGrades() { ....... } <span class="color-comment">// Print the given int array in the form of {x1, x2, x3,..., xn}.</span> public static void printArray(int[] array) { ....... } <span class="color-comment">// Return the average value of the given int[]</span> public static double average(int[] array) { ...... } <span class="color-comment">// Return the median value of the given int[] // Median is the center element for odd-number array, // or average of the two center elements for even-number array. // Use Arrays.sort(anArray) to sort anArray in place.</span> public static double median(int[] array) { ...... } <span class="color-comment">// Return the maximum value of the given int[]</span> public static int max(int[] array) { int max = array[0]; <span class="color-comment">// Assume that max is the first element</span> <span class="color-comment">// From second element, if the element is more than max, set the max to this element.</span> ...... } <span class="color-comment">// Return the minimum value of the given int[]</span> public static int min(int[] array) { ....... } <span class="color-comment">// Return the standard deviation of the given int[]</span> public static double stdDev(int[] array) { ....... } } |
Take note that besides readGrade()
that relies on global variable grades
, all the methods are self-contained general utilities that operate on any given array.
Exercise GradesHistogram (Method): Write a program called GradesHistogram
, which reads in n
grades (as in the previous exercise), and displays the horizontal and vertical histograms. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
0 - 9: *** 10 - 19: *** 20 - 29: 30 - 39: 40 - 49: * 50 - 59: ***** 60 - 69: 70 - 79: 80 - 89: * 90 -100: ** * * * * * * * * * * * * * * * 0-9 10-19 20-29 30-39 40-49 50-59 60-69 70-79 80-89 90-100 |
Hints:
- Declare a 10-element
int
arrays calledbins
, to maintain the counts for[0,9]
,[10,19]
, …,[90,100]
. Take note that thebins
‘s index ismark/10
, exceptmark
of100
. - Write the codes to print the star first. Test it. Then print the labels.
- To print the horizontal histogram, use a nested loop:
12345678for (int binNum = 0; binNum < bins.length; binNum++) { <span class="color-comment">// each row for one bin</span><span class="color-comment">// Print label for each row</span>.......for (int starNum = 0; starNum < bins[binNum]; starNum++) { <span class="color-comment">// each column is one star</span>.......}...... <span class="color-comment">// print newline</span>} - To print the vertical histogram, you need to find the maximum bin count (called
maxBinCount
) and use a nested loop:
1234567for (int level = maxBinCount; level >= 1; level--) { <span class="color-comment">// each row for one count level</span>for (int binNum = 0; binNum < bins.length; binNum++) { <span class="color-comment">// each column for one bin</span><span class="color-comment">// if (bin's count >= level) print *// else print blank.</span>}...... <span class="color-comment">// print newline</span>}
Exercise (Array and Method): Write a program called PrintChart
that prompts the user to input n
non-negative integers and draws the corresponding horizontal bar chart. Your program shall use an int
array of length n
; and comprise methods readInput()
and printChart()
. A sample session is as follows:
1 2 3 4 5 6 7 8 9 10 |
Enter number of bars: <strong>4</strong> Enter bar 1 value: <strong>4</strong> Enter bar 2 value: <strong>3</strong> Enter bar 3 value: <strong>5</strong> Enter bar 4 value: <strong>7</strong> **** (4) *** (3) ***** (5) ******* (7) |
8. Exercises on Command-line Arguments
Exercise Arithmetic (Command-line arguments): Write a program called Arithmetic
that takes three command-line arguments: two integers followed by an arithmetic operator (+
, -
, *
or /
). The program shall perform the corresponding operation on the two integers and print the result. For example:
1 2 3 4 5 6 7 8 |
<strong>java Arithmetic 3 2 +</strong> 3+2=5 <strong>java Arithmetic 3 2 -</strong> 3-2=1 <strong>java Arithmetic 3 2 /</strong> 3/2=1 |
Hints:
The method main(String[] args)
takes an argument: “an array of String
“, which is often (but not necessary) named args
. This parameter captures the command-line arguments supplied by the user when the program is invoked. For example, if a user invokes:
1 |
<strong>java Arithmetic 12345 4567 +</strong> |
The three command-line arguments "12345"
, "4567"
and "+"
will be captured in a String
array {"12345", "4567", "+"}
and passed into the main()
method as the argument args
. That is,
1 2 3 4 5 6 7 8 |
args is: {"12345", "4567", "+"} <span class="color-comment">// args is a String array</span> args.length is: 3 <span class="color-comment">// length of the array</span> args[0] is: "12345" <span class="color-comment">// 1st element of the String array</span> args[1] is: "4567" <span class="color-comment">// 2nd element of the String array</span> args[2] is: "+" <span class="color-comment">// 3rd element of the String array</span> args[0].length() is: 5 <span class="color-comment">// length of 1st String element</span> args[1].length() is: 4 <span class="color-comment">// length of the 2nd String element</span> args[2].length() is: 1 <span class="color-comment">// length of the 3rd String element</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
public class <strong>Arithmetic</strong> { public static void main (String[] args) { int operand1, operand2; char theOperator; <span class="color-comment">// Check if there are 3 command-line arguments in the // String array args[] by using length variable of array.</span> if (args.length != 3) { System.err.println("Usage: java Arithmetic int1 int2 op"); return; } <span class="color-comment">// Convert the 3 Strings args[0], args[1], args[2] to int and char. // Use the Integer.parseInt(aStr) to convert a String to an int.</span> operand1 = Integer.parseInt(args[0]); operand2 = ...... <span class="color-comment">// Get the operator, assumed to be the first character of // the 3rd string. Use method charAt() of String.</span> theOperator = args[2].charAt(0); System.out.print(args[0] + args[2] + args[1] + "="); switch(theOperator) { case ('-'): System.out.println(operand1 - operand2); break; case ('+'): ...... case ('*'): ...... case ('/'): ...... default: System.err.println("Error: invalid operator!"); } } } |
Notes:
- To provide command-line arguments, use the “cmd” or “terminal” to run your program in the form “
java ClassName arg1 arg2 ....
“. - To provide command-line arguments in Eclipse, right click the source code ⇒ “Run As” ⇒ “Run Configurations…” ⇒ Select “Main” and choose the proper main class ⇒ Select “Arguments” ⇒ Enter the command-line arguments, e.g., “3 2 +” in “Program Arguments”.
- To provide command-line arguments in NetBeans, right click the “Project” name ⇒ “Set Configuration” ⇒ “Customize…” ⇒ Select categories “Run” ⇒ Enter the command-line arguments, e.g., “3 2 +” in the “Arguments” box (but make sure you select the proper Main class).
Question: Try “java Arithmetic 2 4 *
” (in CMD shell and Eclipse/NetBeans) and explain the result obtained. How to resolve this problem?
In Windows’ CMD shell, *
is known as a wildcard character, that expands to give the list of file in the directory (called Shell Expansion). For example, “dir *.java
” lists all the file with extension of “.java
“. You could double-quote the * to prevent shell expansion. Eclipse has a bug in handling this, even * is double-quoted. NetBeans??
Exercise SumDigits (Command-line arguments): Write a program called SumDigits
to sum up the individual digits of a positive integer, given in the command line. The output shall look like:
1 2 |
<strong>java SumDigits 12345 </strong>The sum of digits = 1 + 2 + 3 + 4 + 5 = 15 |
9. More (Difficult) Exercises
Exercise (JDK Source Code): Extract the source code of the class Math
from the JDK source code (“$JAVA_HOME
” ⇒ “src.zip
” ⇒ “Math.java
” under folder “java.lang
“). Study how constants such as E
and PI
are defined. Also study how methods such as abs()
, max()
, min()
, toDegree()
, etc, are written.
Exercise Matrix: Similar to Math
class, write a Matrix
library that supports matrix operations (such as addition, subtraction, multiplication) via 2D arrays. The operations shall support bothdouble
s and int
s. Also write a test class to exercise all the operations programmed.
Hints:
1 2 3 4 5 6 7 8 9 |
public class <strong>Matrix</strong> { public static void printMatrix(int[][] m) { ...... } public static void printMatrix(double[][] m) { ...... } public static boolean haveSameDimension(int[][] m1, int[][] m2) { ...... } public static boolean haveSameDimension(double[][] m1, double[][] m2) { ...... } public static int[][] add(int[][] m1, int[][] m2) { ...... } public static double[][] add(double[][] m1, double[][] m2) { ...... } ...... } |
Exercise PrintAnimalPattern (Special Characters and Escape Sequences): Write a program called PrintAnimalPattern
, which uses println()
to produce this pattern:
1 2 3 4 5 6 7 |
'__' (©©) /========\/ / || %% || * ||----|| ¥¥ ¥¥ "" "" |
Hints:
- Use escape sequence
\uhhhh
wherehhhh
are four hex digits to display Unicode characters such as ¥ and ©. ¥ is165
(00A5H
) and © is169
(00A9H
) in both ISO-8859-1 (Latin-1) and Unicode character sets. - Double-quote (
"
) and black-slash (\
) require escape sign inside a String. Single quote ('
) does not require escape sign.
Try: Print the same pattern using printf()
. (Hints: Need to use %%
to print a %
in printf()
because %
is the suffix for format specifier.)
Exercise PrintPatterns: Write a method to print each of the followings patterns using nested loops in a class called PrintPatterns
. The program shall prompt user for the sizde of the pattern. The signatures of the methods are:
1 |
public static void printPatternX(int size) <span class="color-comment">// 'X' from 'A' to ..., size is a positive integer.</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # (a) (b) # # # # # # # # # # # # # # # # # # # # # # # # # (c) 1 1 2 3 4 5 6 7 8 1 8 7 6 5 4 3 2 1 1 2 1 2 3 4 5 6 7 2 1 7 6 5 4 3 2 1 1 2 3 1 2 3 4 5 6 3 2 1 6 5 4 3 2 1 1 2 3 4 1 2 3 4 5 4 3 2 1 5 4 3 2 1 1 2 3 4 5 1 2 3 4 5 4 3 2 1 4 3 2 1 1 2 3 4 5 6 1 2 3 6 5 4 3 2 1 3 2 1 1 2 3 4 5 6 7 1 2 7 6 5 4 3 2 1 2 1 1 2 3 4 5 6 7 8 1 8 7 6 5 4 3 2 1 1 (d) (e) (f) (g) 1 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1 1 2 1 1 2 3 4 5 6 7 6 5 4 3 2 1 1 2 3 2 1 1 2 3 4 5 6 5 4 3 2 1 1 2 3 4 3 2 1 1 2 3 4 5 4 3 2 1 1 2 3 4 5 4 3 2 1 1 2 3 4 3 2 1 1 2 3 4 5 6 5 4 3 2 1 1 2 3 2 1 1 2 3 4 5 6 7 6 5 4 3 2 1 1 2 1 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1 1 (h) (i) 1 1 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1 1 2 2 1 1 2 3 4 5 6 7 7 6 5 4 3 2 1 1 2 3 3 2 1 1 2 3 4 5 6 6 5 4 3 2 1 1 2 3 4 4 3 2 1 1 2 3 4 5 5 4 3 2 1 1 2 3 4 5 5 4 3 2 1 1 2 3 4 4 3 2 1 1 2 3 4 5 6 6 5 4 3 2 1 1 2 3 3 2 1 1 2 3 4 5 6 7 7 6 5 4 3 2 1 1 2 2 1 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1 1 1 (j) (k) 1 2 3 2 3 4 5 4 3 4 5 6 7 6 5 4 5 6 7 8 9 8 7 6 5 6 7 8 9 0 1 0 9 8 7 6 7 8 9 0 1 2 3 2 1 0 9 8 7 8 9 0 1 2 3 4 5 4 3 2 1 0 9 8 (l) |
Exercise PrintTriangles: Write a method to print each of the following patterns using nested-loops in a class called PrintTriangles
. The program shall prompt user for the numRows. The signatures of the methods are:
1 |
public static void printXxxTriangle(int numRows) <span class="color-comment">// Xxx is the pattern's name</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
1 1 2 1 1 2 4 2 1 1 2 4 8 4 2 1 1 2 4 8 16 8 4 2 1 1 2 4 8 16 32 16 8 4 2 1 1 2 4 8 16 32 64 32 16 8 4 2 1 1 2 4 8 16 32 64 128 64 32 16 8 4 2 1 (a) PowerOf2Triangle 1 1 1 1 1 1 1 2 1 1 2 1 1 3 3 1 1 3 3 1 1 4 6 4 1 1 4 6 4 1 1 5 10 10 5 1 1 5 10 10 5 1 1 6 15 20 15 6 1 1 6 15 20 15 6 1 (b) PascalTriangle1 (c) PascalTriangle2 |
Exercise TrigonometricSeries: Write a method to compute sin(x)
and cos(x)
using the following series expansion, in a class called TrigonometricSeries
. The signatures of the methods are:
1 2 |
public static double sin(double x, int numTerms) <span class="color-comment">// x in radians</span> public static double cos(double x, int numTerms) |
Compare the values computed using the series with the JDK methods
Math.sin()
, Math.cos()
at x=0
, π/6
, π/4
, π/3
, π/2
using various numbers of terms.
Hints: Do not use int
to compute the factorial; as factorial of 13 is outside the int
range. Avoid generating large numerator and denominator. Use double
to compute the terms as:
Exercise Exponential Series: Write a method to compute e
and exp(x)
using the following series expansion, in a class called TrigonometricSeries
. The signatures of the methods are:
1 2 |
public static double exp(int numTerms) <span class="color-comment">// x in radians</span> public static double exp(double x, int numTerms) |
Exercise SpecialSeries: Write a method to compute the sum of the series in a class called SpecialSeries
. The signature of the method is:
1 |
public static double sumOfSeries(double x, int numTerms) |
Exercise FibonacciInt (Overflow) : Write a program called FibonacciInt
to list all the Fibonacci numbers, which can be expressed as an int
(i.e., 32-bit signed integer in the range of [-2147483648, 2147483647]
). The output shall look like:
1 2 3 4 5 6 |
F(0) = 1 F(1) = 1 F(2) = 2 ... F(45) = 1836311903 F(46) is out of the range of int |
Hints: The maximum and minimum values of a 32-bit int are kept in constants Integer.MAX_VALUE
and Integer.MIN_VALUE
, respectively. Try these statements:
1 2 3 |
System.out.println(Integer.MAX_VALUE); System.out.println(Integer.MIN_VALUE); System.out.println(Integer.MAX_VALUE + 1); |
Take note that in the third statement, Java Runtime does not flag out an overflow error, but silently wraps the number around. Hence, you cannot use F(n-1) + F(n-2) > Integer.MAX_VALUE
to check for overflow. Instead, overflow occurs for F(n)
if (Integer.MAX_VALUE – F(n-1)) < F(n-2)
(i.e., no room for the next Fibonacci number).
Write a similar program for Tribonacci numbers.
Exercise FactorialInt (Overflow): Write a program called Factorial1to10
, to compute the factorial of n
, for 1≤n≤10
. Your output shall look like:
1 2 3 4 |
The factorial of 1 is 1 The factorial of 2 is 2 ... The factorial of 10 is 3628800 |
Modify your program (called FactorialInt
), to list all the factorials, that can be expressed as an int
(i.e., 32-bit signed integer in the range of [-2147483648, 2147483647]
). Your output shall look like:
1 2 3 4 5 |
The factorial of 1 is 1 The factorial of 2 is 2 ... The factorial of 12 is 479001600 The factorial of 13 is out of range |
Hints: The maximum and minimum values of a 32-bit int
are kept in constants Integer.MAX_VALUE
and Integer.MIN_VALUE
, respectively. Try these statements:
1 2 3 |
System.out.println(Integer.MAX_VALUE); System.out.println(Integer.MIN_VALUE); System.out.println(Integer.MAX_VALUE + 1); |
Take note that in the third statement, Java Runtime does not flag out an overflow error, but silently wraps the number around.
Hence, you cannot use F(n) * (n+1) > Integer.MAX_VALUE
to check for overflow. Instead, overflow occurs for F(n+1)
if (Integer.MAX_VALUE / Factorial(n)) < (n+1)
, i.e., no room for the next number.
Try: Modify your program again (called FactorialLong
) to list all the factorial that can be expressed as a long
(64-bit signed integer). The maximum value for long
is kept in a constant calledLong.MAX_VALUE
.
Exercise Fibonacci (Overflow): Write a program called FibonacciInt
to list all the Fibonacci numbers, which can be expressed as an int
(i.e., 32-bit signed integer in the range of[-2147483648, 2147483647]
). The output shall look like:
1 2 3 4 5 6 |
F(0) = 1 F(1) = 1 F(2) = 2 ... F(45) = 1836311903 F(46) is out of the range of int |
Hints: The maximum 32-bit int
is kept in constant Integer.MAX_VALUE
. You cannot use F(n-1) + F(n-2) > Integer.MAX_VALUE
to check for overflow. Instead, overflow occurs for F(n)
if(Integer.MAX_VALUE – F(n-1)) < F(n-2)
, i.e., no room for the next number.
Try: Write a similar program for Tribonacci numbers.
Exercise NumberConversion: Write a method call toRadix()
which converts a positive integer from one radix into another. The method has the following header:
1 |
public static String toRadix(String in, int inRadix, int outRadix) <span class="color-comment">// The input and output are treated as String.</span> |
Write a program called NumberConversion
, which prompts the user for an input number, an input radix, and an output radix, and display the converted number. The output shall look like:
1 2 3 4 |
Enter a number and radix: <strong>A1B2</strong> Enter the input radix: <strong>16</strong> Enter the output radix: <strong>2</strong> "A1B2" in radix 16 is "1010000110110010" in radix 2. |
Exercise NumberGuess: Write a program called NumberGuess
to play the number guessing game. The program shall generate a random number between 0
and 99
. The player inputs his/her guess, and the program shall response with “Try higher”, “Try lower” or “You got it in n trials” accordingly. For example:
1 2 3 4 5 6 7 8 9 10 |
<strong>java NumberGuess</strong> Key in your guess: <strong>50</strong> Try higher <strong>70</strong> Try lower <strong>65</strong> Try lower <strong>61</strong> You got it in 4 trials! |
Hints: Use Math.random()
to produce a random number in double
between 0.0
and (less than) 1.0
. To produce an int between 0
and 99
, use:
1 |
int secretNumber = (int)(Math.random()*100); |
Exercise WordGuess: Write a program called WordGuess
to guess a word by trying to guess the individual characters. The word to be guessed shall be provided using the command-line argument. Your program shall look like:
1 2 3 4 5 6 7 8 9 10 |
<strong>java WordGuess testing</strong> Key in one character or your guess word: <strong>t</strong> Trial 1: t__t___ Key in one character or your guess word: <strong>g</strong> Trial 2: t__t__g Key in one character or your guess word: <strong>e</strong> Trial 3: te_t__g Key in one character or your guess word: <strong>testing</strong> Congratulation! You got in 4 trials |
Hints:
- Set up a
boolean
array to indicate the positions of the word that have been guessed correctly. - Check the length of the input
String
to determine whether the player enters a single character or a guessed word. If the player enters a single character, check it against the word to be guessed, and update theboolean
array that keeping the result so far. - Try retrieving the word to be guessed from a text file (or a dictionary) randomly.
Exercise DateUtil: Complete the following methods in a class called DateUtil
:
boolean isLeapYear(int year)
: returnstrue
if the givenyear
is a leap year. A year is a leap year if it is divisible by 4 but not by 100, or it is divisible by 400.boolean isValidDate(int year, int month, int day)
: returnstrue
if the givenyear
,month
andday
constitute a given date. Assume that year is between 1 and 9999, month is between 1 (Jan) to 12 (Dec) and day shall be between 1 and 28|29|30|31 depending on the month and whether it is a leap year.int getDayOfWeek(int year, int month, int day)
: returns the day of the week, where 0 for SUN, 1 for MON, …, 6 for SAT, for the given date. Assume that the date is valid.String toString(int year, int month, int day)
: prints the given date in the format “xxxday d mmm yyyy
“, e.g., “Tuesday 14 Feb 2012”. Assume that the given date is valid.
To find the day of the week (Reference: Wiki “Determination of the day of the week”):
- Based on the first two digit of the year, get the number from the following “century” table.
1700- 1800- 1900- 2000- 2100- 2200- 2300- 2400- 4 2 0 6 4 2 0 6 Take note that the entries 4, 2, 0, 6 repeat.
- Add to the last two digit of the year.
- Add to “the last two digit of the year divide by 4, truncate the fractional part”.
- Add to the number obtained from the following month table:
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Non-Leap Year 0 3 3 6 1 4 6 2 5 0 3 5 Leap Year 6 2 same as above - Add to the day.
- The sum modulus 7 gives the day of the week, where 0 for SUN, 1 for MON, …, 6 for SAT.
For example: 2012, Feb, 17
1 |
(6 + 12 + 12/4 + 2 + 17) % 7 = 5 (Fri) |
The skeleton of the program is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<span class="color-comment">/* Utilities for Date Manipulation */</span> public class <strong>DateUtil</strong> { <span class="color-comment">// Month's name – for printing</span> public static String strMonths[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; <span class="color-comment">// Number of days in each month (for non-leap years)</span> public static int daysInMonths[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; <span class="color-comment">// Returns true if the given year is a leap year</span> public static boolean isLeapYear(int year) { ...... } <span class="color-comment">// Return true if the given year, month, day is a valid date</span> <span class="color-comment">// year: 1-9999</span> <span class="color-comment">// month: 1(Jan)-12(Dec)</span> <span class="color-comment">// day: 1-28|29|30|31. The last day depends on year and month</span> public static boolean isValidDate(int year, int month, int day) { ...... } <span class="color-comment">// Return the day of the week, 0:Sun, 1:Mon, ..., 6:Sat</span> public static int getDayOfWeek(int year, int month, int day) { ...... } <span class="color-comment">// Return String "xxxday d mmm yyyy" (e.g., Wednesday 29 Feb 2012)</span> public static String printDate(int year, int month, int day) { ...... } public static void main(String[] args) { System.out.println(isLeapYear(1900)); <span class="color-comment">// false</span> System.out.println(isLeapYear(2000)); <span class="color-comment">// true</span> System.out.println(isLeapYear(2011)); <span class="color-comment">// false</span> System.out.println(isLeapYear(2012)); <span class="color-comment">// true</span> System.out.println(isValidDate(2012, 2, 29)); <span class="color-comment">// true</span> System.out.println(isValidDate(2011, 2, 29)); <span class="color-comment">// false</span> System.out.println(isValidDate(2099, 12, 31)); <span class="color-comment">// true</span> System.out.println(isValidDate(2099, 12, 32)); <span class="color-comment">// false</span> System.out.println(getDayOfWeek(1982, 4, 24)); <span class="color-comment">// 6:Sat</span> System.out.println(getDayOfWeek(2000, 1, 1)); <span class="color-comment">// 6:Sat</span> System.out.println(getDayOfWeek(2054, 6, 19)); <span class="color-comment">// 5:Fri</span> System.out.println(getDayOfWeek(2012, 2, 17)); <span class="color-comment">// 5:Fri</span> System.out.println(toString(2012, 2, 14)); <span class="color-comment">// Tuesday 14 Feb 2012</span> } } |
You can compare the day obtained with the Java’s Calendar
class as follows:
1 2 3 4 5 6 7 8 |
<span class="color-comment">// Construct a Calendar instance with the given year, month and day</span> Calendar cal = new GregorianCalendar(year, month - 1, day); <span class="color-comment">// month is 0-based</span> <span class="color-comment">// Get the day of the week number: 1 (Sunday) to 7 (Saturday)</span> int dayNumber = cal.get(Calendar.DAY_OF_WEEK); String[] calendarDays = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; <span class="color-comment">// Print result</span> System.out.println("It is " + calendarDays[dayNumber - 1]); |
The calendar we used today is known as Gregorian calendar, which came into effect in October 15, 1582 in some countries and later in other countries. It replaces the Julian calendar. 10 days were removed from the calendar, i.e., October 4, 1582 (Julian) was followed by October 15, 1582 (Gregorian). The only difference between the Gregorian and the Julian calendar is the “leap-year rule”. In Julian calendar, every four years is a leap year. In Gregorian calendar, a leap year is a year that is divisible by 4 but not divisible by 100, or it is divisible by 400, i.e., the Gregorian calendar omits century years which are not divisible by 400. Furthermore, Julian calendar considers the first day of the year as march 25th, instead of January 1st.
This above algorithm work for Gregorian dates only. It is difficult to modify the above algorithm to handle pre-Gregorian dates. A better algorithm is to find the number of days from a known date.
10. Exercises on Recursion
In programming, a recursive function calls itself. The classical example is factorial(n)
, which can be defined recursively as n*factorial(n-1)
. Nonethessless, it is important to take note that a recursive function should have a terminating condition (or base case), in the case of factorial, factorial(0)=1
. Hence, the full definition is:
1 2 |
factorial(n) = 1, for n = 0 factorial(n) = n * factorial(n-1), for all n > 1 |
For example, suppose n = 5
:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<span class="color-comment">// Recursive call</span> factorial(5) = 5 * factorial(4) factorial(4) = 4 * factorial(3) factorial(3) = 3 * factorial(2) factorial(2) = 2 * factorial(1) factorial(1) = 1 * factorial(0) factorial(0) = 1 <span class="color-comment">// Base case</span> <span class="color-comment">// Unwinding</span> factorial(1) = 1 * 1 = 1 factorial(2) = 2 * 1 = 2 factorial(3) = 3 * 2 = 6 factorial(4) = 4 * 6 = 24 factorial(5) = 5 * 24 = 120 (DONE) |
Exercise (Factorial) (Recursive): Write a recursive method called factorial()
to compute the factorial of the given integer.
1 |
public static int factorial(int n) |
The recursive algorithm is:
1 2 |
factorial(n) = 1, if n = 0 factorial(n) = n * factorial(n-1), if n > 0 |
Compare your code with the iteractive version of the factorial()
:
1 |
factorial(n) = 1*2*3*...*n |
Hints:
1 2 3 4 5 6 7 8 9 10 |
<span class="color-comment">// Return the factorial of the given integer, recursively</span> public static int factorial(int n) { if (n == 0) { return 1; <span class="color-comment">// base case</span> } else { return n * factorial(n-1); <span class="color-comment">// call itself</span> } <span class="color-comment">// or one line</span>r // return (n == 0) ? 1 : n*factorial(n-1); } |
Notes:
- Recursive version is often much shorter.
- The recursive version uses much more computation and storage resources, and it need to save its states before each successive recursive call.
Exercise (Fibonacci) (Recursive): Write a recursive method to compute the Fibonacci sequence of n, defined as follows:
1 2 3 |
F(0) = 0 F(1) = 1 F(n) = F(n-1) + F(n-2) for n >= 2 |
Compare the recursive version with the iteractive version written earlier.
Exercise (A Running Number Sequence) (Recursive): A special number sequence is defined as follows:
1 2 3 4 5 6 7 8 9 |
S(1) = 1 S(2) = 12 S(3) = 123 S(4) = 1234 ...... S(9) = 123456789 <span class="color-comment">// length is 9</span> S(10) = 12345678910 <span class="color-comment">// length is 11</span> S(11) = 1234567891011 <span class="color-comment">// length is 13</span> ...... |
Write a recursive method to compute the length of S(n)
. Also write an iteractive version.
Exercise (GCD) (Recursive): Write a recursive method called gcd()
to compute the greatest common divisor of two given integers.
1 2 3 4 |
public static void int gcd(int a, int b) gcd(a,b) = a, if b = 0 gcd(a,b) = gcd(b, remainder(a,b)), if b > 0 |
Exercise (Tower of Hanoi Recursive) (Recursive): [TODO]
11. Exercises on Algorithms – Sorting and Searching
Efficient sorting and searching are big topics, typically covered in a course called “Data Structures and Algorithms”. There are many searching and sorting algorithms available, with their respective strengths and weaknesses. See Wikipedia “Sorting Algorithms” and “Searching Algorithms” for the algorithms, examples and illustrations.
JDK provides searching and sorting utilities in the Arrays
class (in package java.util
), such as Arrays.sort()
and Arrays.binarySearch()
– you don’t have to write your searching and sorting in your production program. These exercises are for academic purpose and for you to gain some understandings and practices on these algorithms.
Exercise (Linear Search): (Reference: Wikipedia “Linear Search”) Compare each item with the search key in the linear manner. Linear search is applicable to unsorted list.
1 2 3 4 5 |
<span class="color-comment">// Return the array index, if key is found; or 0 otherwise</span> public static int linearSearch(int[] array, int key) <span class="color-comment">// or</span> <span class="color-comment">// Return true if the key is found</span> public static boolean linearSearch(int[] array, int key) |
Exercise (Recursive Binary Search): (Reference: Wikipedia “Binary Search”) Binary search is only applicable to a sorted list.
For example, suppose that we want to search for the item 18
in the list {11 14 16 18 20 25 28 30 34 40 45}
:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Create two indexes: firstIdx and lastIdx, initially pointing at the first and last elements {11 14 16 18 20 25 28 30 34 40 45} F M L Compute middleIdx = (firstIdx + lastIdx) / 2 Compare the key (K) with the middle element (M) If K = M, return true else if K < M, set L = M else if K > M, set F = M {11 14 16 18 20 25 28 30 34 40 45} F M L Recursively Repeat the search between the new F and L. Terminate at F = L. {11 14 16 18 20 25 28 30 34 40 45} F M L |
Write a recursive function called binarySearch()
as follows:
1 2 |
<span class="color-comment">// Return true if key is found in the array in the range of fromIdx (inclusive), toIdx (exclusive)</span> public boolean binarySearch(int[] array, int key, int fromIdx, int toIdx) |
Use the following pesudocode implementation:
1 2 3 4 5 6 7 8 9 |
If fromIdx = toIdx - 1 <span class="color-comment">/* one-element list */</span> if key = A[fromIdx], return true else, return false (not found) else middleIdx = (fromIdx + toIdx) / 2 if key = A[middleIdx], return true else if key < A[middleIdx], toIdx = middleIdx else firstIdx = middleIdx + 1 binarySearch(array, key, fromIdx, toIdx) |
Also write an overloaded method which uses the above to search the entire array:
1 2 |
<span class="color-comment">// Return true if key is found in the array</span> public boolean binarySearch(int[] array, int key) |
Exercise (Bubble Sort): (Reference: Wikipedia “Bubble Sort”) The principle is to scan the elements from left-to-right, and whenever two adjacent elements are out-of-order, they are swapped. Repeat the passes until no swap are needed.
For example, given the list {9 2 4 1 5}
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Pass 1: <span class="color-new">9 2</span> 4 1 5 -> <span class="color-new">2 9</span> 4 1 5 2 <span class="color-new">9 4</span> 1 5 -> 2 <span class="color-new">4 9</span> 1 5 2 4 <span class="color-new">9 1</span> 5 -> 2 4 <span class="color-new">1 9</span> 5 2 4 1 <span class="color-new">9 5</span> -> 2 4 1 <span class="color-new">5 <span class="underline">9</span></span> (After Pass 1, the largest item sorted on the right - bubble to the right) Pass 2: <span class="color-new">2 4</span> 1 5 9 -> <span class="color-new">2 4</span> 1 5 9 2 <span class="color-new">4 1</span> 5 9 -> 2 <span class="color-new">1 4</span> 5 9 2 1 <span class="color-new">4 5</span> 9 -> 2 1 <span class="color-new">4 5</span> 9 2 1 4 <span class="color-new">5 9</span> -> 2 1 4 <span class="color-new"><span class="underline">5 9</span></span> (After Pass 2, the 2 largest items sorted on the right) Pass 3: <span class="color-new">2 1</span> 4 5 9 -> <span class="color-new">1 2</span> 4 5 9 1 <span class="color-new">2 4</span> 5 9 -> 1 <span class="color-new">2 4</span> 5 9 1 2 <span class="color-new">4 5</span> 9 -> 1 2 <span class="color-new">4 5</span> 9 1 2 4 <span class="color-new">5 9</span> -> 1 2 <span class="underline">4 <span class="color-new">5 9</span></span> (After Pass 3, the 3 largest items sorted on the right) Pass 4: <span class="color-new">1 2</span> 4 5 9 -> <span class="color-new">1 2</span> 4 5 9 1 <span class="color-new">2 4</span> 5 9 -> 1 <span class="color-new">2 4</span> 5 9 1 2 <span class="color-new">4 5</span> 9 -> 1 2 <span class="color-new">4 5</span> 9 1 2 4 <span class="color-new">5 9</span> -> 1 <span class="underline">2 4 <span class="color-new">5 9</span></span> (After Pass 4, the 4 largest items sorted on the right) No Swap in Pass 4. Done. |
See Wikipedia “Bubble Sort” for more examples and illustration.
Write a method to sort an int
array (in place) with the following signature:
1 |
public static void bubbleSort(int[] array) |
Use the following pesudocode implementation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
function bubbleSort(A) n = length(A) boolean swapped <span class="color-comment">/* boolean flag to indicate swapping occurred during a pass */</span> do <span class="color-comment">/* a pass */</span> swapped = false <span class="color-comment">/* reset for each pass */</span> for i = 1 to n-1 <span class="color-comment">/* if this pair is out of order */</span> if A[i-1] > A[i] then <span class="color-comment">/* swap them and take note something changed */</span> swap( A[i-1], A[i] ) swapped = true end if end for n = n - 1 <span class="color-comment">/* One item sorted after each pass */</span> while (swapped) <span class="color-comment">/* repeat another pass if swapping occurred */</span> end function |
Exercise (Selection Sort): (Reference: Wikipedia “Selection Sort”) This algorithm divides the lists into two parts: the left-sublist of items already sorted, and the right-sublist for the remaining items. Initially, the left-sorted-sublist is empty, while the right-unsorted-sublist is the entire list. The algorithm proceeds by finding the smallest (or largest) items from the right-unsorted-sublist, swapping it with the leftmost element of the right-unsorted-sublist, and increase the left-sorted-sublist by one.
For example, given the list {9 6 4 1 5}
:
1 2 3 4 5 6 |
{} {<span class="color-new">9</span> 6 4 <span class="color-new">1</span> 5} -> {} {<span class="color-new">1</span> 6 4 <span class="color-new">9</span> 5} {1} {<span class="color-new">6</span> <span class="color-new">4</span> 9 5} -> {1} {<span class="color-new">4</span> <span class="color-new">6</span> 9 5} {1 4} {<span class="color-new">6</span> 9 <span class="color-new">5</span>} -> {1 4} {<span class="color-new">5</span> 9 <span class="color-new">6</span>} {1 4 5} {<span class="color-new">9</span> <span class="color-new">6</span>} -> {1 4 5} {<span class="color-new">6</span> <span class="color-new">9</span>} |