Document

advertisement
Take-Home Lab #01
CS1020 – DATA STRUCTURES AND ALGORITHMS 1
AY2015-16 SEMESTER 2
Problem 1
Measurement
You are given a number N.
 N rows follow.


Each row contains:
•
•
•
Name of a student
Height of a student (in cm)
Weight of a student (in kg)
Measurement
How?
Data
Storing
Data
Processing
Measurement
Array Solution
VS
Non-Array
Solution
Measurement
Array solution

Store the height, weight, and name of each student in an
array of the appropriate data type.

Linear scan the height[] array, keeping the index of the
maximum and minimum height.

Retrieve the height, weight and name of the tallest student
and the shortest student using the index you got from the
previous step.

Calculate the BMI and print the result.
Measurement
Non-Array solution

We do not actually need to store all the data in an array.

Initialise variables that keep track of the minimum height so
far, maximum height so far, as well as the name and height
of both the (current) tallest and (current) shortest student.

Read the input using a scanner, update the variables when
necessary.
When is it necessary to
update the variables
above?

Calculate the BMI and print the result.
Measurement
Code Snippet
Scanner sc = new Scanner(System.in);
Initialise
Variables
int heightOfCurrentShortestStudent = Integer.MAX_VALUE;
int heightOfCurrentTallestStudent = Integer.MIN_VALUE;
int weightOfCurrentShortestStudent = 0;
int weightOfCurrentTallestStudent = 0;
String nameOfCurrentShortestStudent = "";
String nameOfCurrentTallestStudent = "";
Measurement
Code Snippet
for (int i = 0; i < n; i++) { //for every line of the input
String currentName = ??? (use your Scanner here)
//how to get the name of the current student?
int currentHeight = ???
//how to get the height of the current student?
int currentWeight = ???
//how to get the weight of the current student?
Process
Input
if (currentHeight < heightOfCurrentShortestStudent) {
//what do you need to do here?
}
if (currentHeight > heightOfCurrentTallestStudent) {
//what do you need to do here?
}
sc.nextLine(); //what is the purpose of this?
}
Measurement
?
How do I print to
two decimal places?
Hint: System.out.printf(…);
Measurement
Problem 2
Island

You are given a map of Hyrule consisting of many islands.

The map is a matrix of size R x C filled with ‘0’s and ‘1’s.

Your job: count the number of islands based on the given
map (you need N tickets to go to N islands).
0
0
0
0
0
0
0
1
1
1
0
0
0
1
1
1
0
0
0
1
1
1
0
0
0
0
0
0
1
1
An example of a
valid Hyrule map
with two islands
Island
Standard (Tedious-To-Code) Solution
VS
(Very) Simple Solution
Island
Hints:
1. All islands are rectangular.
2. Every plot of land is a part
of an island
?
Any
Ideas?
Island
Standard Solution

Step 1: Find the top-left corner of each island.
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if(map[i][j] == 1) {
//Step 2
//Step 3
//use a counter
}
}
}
Island
Standard Solution

Step 2: Find the width (and height) of that island.
int position = i;
while (map[position][j]==1) position++;
//then how do you know the width of this
island?
Similar
for height
Island
Standard Solution

Step 3: How to avoid repeated count?
Update the ‘1’s on the
current island to be ‘0’s
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
1
0
0
1
1
1
0
0
0
0
0
0
0
1
1
1
0
0
1
1
1
0
0
0
0
0
0
0
1
1
1
0
0
1
1
1
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
1
0
0
0
0
1
0
0
0
0
1
0
0
0
0
1
0
0
0
0
1
Island
Easy “Lazy” Solution

Step 1: Find the top-left corner of each island, with a twist.
0
Look for this pattern:
0
1
Increment counter each time you see that pattern
?
What if the “1” is on
the left or top of the
map?
Island
1
1
0
1
1
1
1
0
0
0
1
1
0
0
0
0
0
0
1
1
Trick
Island
Technique
Technique: Just add a row and column of ‘0’s to the map
 Such extra data are called sentinels.

1 1 1 0 0
1 1 1 0 0
1 1 1 0 0
0 0 0 1 1
Island
Technique
Technique: Just add a row and column of ‘0’s to the map
 Such extra data are called sentinels.

0 0 0 0 0 0
0 1 1 0 1 1
0 1 1 0 0 0
0 1 1 0 0 0
0 0 0 0 1 1
count = 3
Island
Our Sample Input
Another Example
(after adding a row and column of ‘0’s)
(after adding a row and column of ‘0’s)
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 1 1 0 0 0
0 0 1 1 1 0
0 1 1 0 0 0
0 0 1 1 1 0
0 0 0 1 1 1
0 0 1 1 1 0
0 0 0 1 1 1
0 0 0 0 0 1
0 1 1 0 0 0
0 0 0 0 0 1
0 1 1 0 0 0
count = 2
count = 3
Island
Code Snippet
for (int i = 1; i <= row; i++) {//why start from 1?
for (int j = 1; j <= col; j++) {
if (isTopLeftCornerOfAnIsland(map, i, j)) {
count++;
}
}
}
boolean isTopLeftCornerOfAnIsland(int[][] map, int i, int j) {
return map[i][j] == 1
&& map[i-1][j] == 0
&& map[i][j-1] == 0;
}
Island
Problem 3
Find X
Question
Map is divided into RxC squares, (R rows, C columns)
‘Super X’
◦ Square of size at least 3
◦ Composed entirely by X on both diagonals.
Find the number of ‘Super X’ in the grid
Find X
25
Super X
7
X
6
X
X
X
X
7
X
X
X
X
X
X
6
X
X
X
X
X
X
X
X
X
X
X
X
X
X
6 x 6 Super X
7 x 7 Super X
Find X
Is this a Super X?
9
X
X
X
X
X
X
7
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
Find X
•
•
•
•
Square?
At least size 3?
All Xs on left diagonal?
All Xs on right diagonal?
Breakdown
Read Input
Calculate number of Super-X
Print Output
Find X
Read Input
1st line contains two numbers R (no. of rows) and C
(no. of columns)
◦ Use nextInt()
Next R line contains C characters each. Each line
represents one row in the treasure map.
◦ Read each row using nextLine() or next();
◦ For loop that iterates C time
Find X
Store Map
Option 1:
◦ String[] map = new String[R];
◦ Each element of the array in the entire row
◦ Use String.charAt(c) to read each element in the row later
Option 2:
◦ char[][] map = new char[R][C]
◦ Read entire row first (String row = sc.nextLine();)
◦ Use row.toCharArray()
◦ Break the row up into its separate elements as a char[]
◦ String[][] map will work too
◦ Use row.split(“”);
Find X
An array of character arrays?
char[][] map = new char[R][C]
new char[8][7];
7
X
X
X
X
map[0]
map[1]
map[3][0]
X
X
X
X
X
X
8
X
X
map[2]
map[3]
X
X
map[4]
X
X
map[5]
X
X
map[6]
map[7]
map[7][4]
Find X
Input
public static void main(String[] args) {
//read input using Scanner
Scanner = new Scanner(System.in);
int R = sc.nextInt(); //number of rows
int C = sc.nextInt(); //number of columns
char[][] map = new char[R][C]; //initialise
sc.nextLine(); //to move onto the next line
//for each row
for (int i = 0; i < numOfRows; i++) {
String rowString = sc.nextLine();
map[i] = rowString.toCharArray();
}
}
Find X
Output
From question:
◦ The number of ‘super X’ in the map
Just use the println() method to print the output
Do not print other strings with the number
◦ E.g. “Number of Super X is: 4”
public static void main(String[] args) {
//read input using Scanner
…..
int count = getNumOfSuperX(map);
System.out.println(count);
}
Find X
Breaking it down
Find the number of squares with ‘Super X’ of size
larger than 3 in the grid
For all the squares of the different sizes in the grid
◦ Check whether it is a Super X
For each size
◦ For each square in the grid of that size
◦ Check whether it is a super X
Find X
Incremental Programming
Breaking the problem down into sub-problems
Solve each of them separately
Create a method that when given a square, will tell
us if it is a super X
Call that method for each of the square of each size
later
Find X
From the centre
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
Expand in all 4 directions
Possible, but tricky
Find X
X
X
X
X
X
X
X
Checking if a square is a super X
Super X’
◦ Square of size at least 3
◦ Composed entirely by X on both diagonals.
Check if both diagonals
of a square are all Xs
7
X
X
X
X
7
X
X
X
X
X
X
X
X
6
X
6
X
X
X
X
X
Find X
X
X
X
X
X
X
X
Checking if a square is a super X
isSuperX method
X
X
Parameters
X
X
◦ Top left corner
X
◦ rowIndex of top left hand corner
◦ columnIndex of top left hand corner
X
X
X
◦ size of square (number of elements in
each row/col)
X
X
Find X
X
X
X
X
Checking if a square is a super X
Iterate through both diagonals (from top left and from top
right)
Check if they are all Xs
2 methods
◦ isRightToLeftAllX
◦ isLeftToRightAllX
Find X
Checking if a square is a super X
//Assume rowNum and colNum are within grid, rowNum + size –
//1 and colNum + size – 1 are within grid
boolean isSuperX(int rowNum, int colNum, int size) {
//can put an if condition here that will return
//false if the square is outside of the grid
int leftCornerCol = colNum;
int rightCornerCol = colNum + size – 1;
int row = rowNum;
return isLeftToRightAllX(leftCornerCol, row, size) &&
isRightToLeftAllX(rightCornerCol, row, size)
Find X
Iterating through the diagonal
boolean isLeftToRightAllX(int x, int y, int size) {
//for size times
for (int i = 0; i < size; i++) {
char currentElement = map[x][y];
if (currentElement != ‘X’) {
return false; //stop evaluating
} else {
x += 1; //advance
y += 1;
}
}
return true;
}
Find X
Hooray!
Now we have our isSuperX method!
◦ Given the row and column of the top left hand corner
◦ We can check if it is a super X! :D
Just call this method for
◦ All squares of each size
◦ Across different sizes
Find X
Iterate through all squares
Assume fixed size of 3
Iterate through the top left corner of each square
Pseudocode here -> try to work it out yourself!
int
int
int
for
size = 3; //assume size 3
R, int C; //from earlier
count;
row = 0 -> R - size
for col = 0 -> C – size
//row & col: top left corner
if isSuperX(row, col, size)
increment count
Find X
Iterating through the sizes of
square
For loop!
X
Start and end?
X
X
Smallest size of square
X
X
X
◦3
X
X
X
Largest size of square
X
◦ min(numRows, numCols)
X
X
Find X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
Pseudocode
maxSize = min(R, C);
//for each size
for size = 3 -> maxSize:
//for each row
for row = 0 -> R - size
//for each column in the row
for col = 0 -> C – size
//row & col: top left corner
if isSuperX(row, col, size)
increment count
Find X
Programming Style
Pre-conditions and Post-conditions (5% of overall)
Above every method
◦
◦
◦
◦
Describe what method is used for
Explain its parameters, and what it returns
Pre-condition: conditions that must be met before algorithm is called
Post-condition: conditions that must be met after algorithm is called
Find X
/**
*Checks if the square in the map is a super X
*
*Pre-condition: rowNum and colNum are the row and
*column of the top left hand corner of the square.
*size is the width of the square. rowNum, colNum,
*rowNum+size-1 and colNum+size-1 are within the map
*Post-condition: Returns true if both diagonals of the
square are X
**/
boolean isSuperX(int rowNum, int colNum, int size) {
….
}
Find X
Programming Style (for Sit-In Labs)
Meaningful comments to explain how your algorithm works
◦ Iterating through the centre of the square?
◦ Iterating through the top left corner of the square?
Don’t just use 1 main method
◦ Incremental programming
◦ Solve each sub-problem one at a time in a separate method
Meaningful variables
◦ Only use single characters for variables given in the input format or
for loop variables
Find X
In summary
Spend some time understanding and formulating your
approach to the problem
Break down the main problem into sub-problems
◦ Iterating through different sizes
◦ Iterating through the squares of each size
◦ Check if square is a super X
Try to understand what the definition is
◦ What exactly is a super X?
◦ A square with both diagonals of only X
Find X
End Of File
Any Questions?
Download