All Exercises in This Part
Create a class List. Define an array inside it for storing the elements of the list, as well as an integer variable that keeps track of the current number of elements in the list.
Implement the method:
add(T element): adds an element to the end of the list.
At this stage, you do not need to increase the size of the data structure, so the array may become full.
Use the debugger to verify that the element has been added correctly.
Do not implement get or toString methods yet; inspect the state of the list specifically through the debugger.
Modify the add method so that it adds an element to the end of the list and, if necessary, creates a new larger array (1.5× or 2× the current size) and copies the elements from the old array into the new one. Remember to update the list size appropriately.
Also implement a size() method that returns the current number of elements in the list.
Use the get and size methods to help test that the add method works correctly even when the array is full and a new array has been created.
Implement a remove(int index) method that removes an element from the list at the specified index. The method must return the removed element.
- Elements following the removed element must be shifted to the left so that no "gaps" remain in the array.
- No unnecessary contents may remain in the array after removal.
- Remember to update the size of the list appropriately.
Use the debugger and/or the get and size methods to verify that the removal was performed correctly.
Continue the List class by implementing the remove(T element) method, which removes the first occurrence of the given element.
- If the element is found and removed, return
true. - If the element is not found, the list remains unchanged and the method returns
false.
Hint: You can use the remove(int index) method you have already implemented. Do not duplicate the element-shifting logic in this method.
Create a function countWords that takes a string as a parameter and performs the following tasks:
- Prints all unique words and the number of times each word appears in the string.
- Prints the most common word separately, along with the number of times it appears in the string.
- Prints the number of unique words.
You can test your program using the provided main program, which also includes sample output.
Hint
You can remove punctuation from the string using its replaceAll method.
Create a class Reservations that stores reservations. There can be only one reservation for a given date, and the name of the person making the reservation must also be stored.
In this exercise, you may represent dates as strings in the format YYYY-MM-DD (year-month-day). You may also assume that all dates are always in the correct format.
Implement the following methods:
-
addReservationtakes a date and the reservation holder's name as string parameters and adds the reservation to the data structure. If a reservation already exists for that date, the new reservation must not replace it. The method returnstrueif the reservation is added, otherwisefalse. -
removeReservationtakes a date as a parameter and removes the reservation for that date. The method returnstrueif the reservation is removed from the data structure, otherwisefalse. -
printReservationstakes a start date and an end date as parameters and prints all reservations that fall within that range, sorted by reservation date.
You can test the functionality of the class using the provided main program.
Hint
In this case, it is not advisable to sort the data structure manually. One of the classes implementing the Map interface keeps its elements automatically sorted.
Implement your own simple hash table.
Use an array as the main data structure of the hash table. To handle collisions, you may use a list, for example, so that elements that end up at the same index are stored in a list located at that index. Elements must not be lost when collisions occur.
The hash table capacity may have a default value of 10, or it may be provided as a constructor parameter. The capacity does not need to change at any point during program execution, so you do not need to consider or implement load factor handling.
Java's hashCode method can return a negative value, so it is a good idea to use the absolute value to avoid negative indices.
Add a get method that retrieves an element from the hash table based on its key.
Also add add and remove methods for inserting and removing elements.
You are given two lists of numbers that contain duplicates.
Create the following sets from these numbers:
-
Union: Contains all numbers that belong to the first set, the second set, or both.
-
Intersection: Contains only the numbers that are present in both sets at the same time.
-
Difference: Contains the numbers that belong to the first set but do not belong to the second set.
-
Symmetric Difference: Contains the numbers that belong to exactly one of the sets, but not both.
The sets must not contain duplicates.
The sets can be created using the methods defined by the Set api, so there is no need to iterate through the data structures with loops.
The provided main program contains examples of what these sets should contain.
Create a class TaskList that acts as a todo list. Tasks can be simple strings.
The task list keeps track of both incomplete and completed tasks. Tasks are completed in the same order in which they were added to the task list. For exceptional situations, it must be possible to add urgent tasks directly to the beginning of the task list.
The program must also provide a way to undo marking a task as completed in case a task is accidentally marked as completed too early. Undoing should return the completed task to the beginning of the task list.
Add the following methods to the class:
-
addTask, which adds a task to the task list. A new task is added to the end of the task list. -
addImportantTask, which adds an urgent task to the task list. An urgent task is always placed at the beginning of the task list. -
markDone, which marks the next task in the task list as completed. -
undoDone, which moves the most recently completed task from the completed tasks list back to the beginning of the task list. -
print, which prints the incomplete and completed tasks as separate lists. The exact output format is not very important, as long as the different lists can be clearly distinguished.
You can test the functionality of the class using the provided main program.
Write a function that checks the correctness of the brackets contained in a string. The function must determine whether all brackets are properly closed in the correct order and whether every opening bracket has a matching closing bracket.
Supported bracket types are:
- Parentheses
( ) - Square brackets
[ ] - Curly braces
{ }
Logic and Rules:
-
Nesting: Brackets may be nested (e.g.
([])), but they must not cross. For example,([)]is invalid because the brackets cross each other. -
Order: A bracket must always be opened before it is closed.
-
Other characters, such as letters or numbers, should be ignored.
-
An empty string is considered valid and contains 0 pairs.
Return Value:
- If the brackets are valid, return the number of bracket pairs found (an integer).
- If the bracket structure is invalid (even a single missing pair or incorrect ordering), return
-1.
Examples:
| String | Result | Explanation |
|---|---|---|
"" | 0 | Empty input is valid, 0 pairs. |
"()" | 1 | One valid pair. |
"(())" | 2 | Two nested pairs. |
"([])" | 2 | Two nested pairs. |
"()[]" | 2 | Two adjacent pairs. |
"a(b)c" | 1 | Letters are ignored, one pair. |
"(" | -1 | Missing closing bracket. |
"(()" | -1 | One closing bracket is missing. |
"()}" | -1 | Extra closing bracket. |
")(" | -1 | Incorrect order (missing opening bracket at the beginning). |
"([)]" | -1 | Brackets cross (invalid nesting). |
The function should be implemented so that if new bracket types are added in the future, no changes are required in the core validation logic.
For example, to support the string a<(b)>c, it should be sufficient to add support for angle brackets < >, while keeping the rest of the logic unchanged (in other words, no additional if statements should be needed).
Calculate the sum 1 + 2 + ... + n without recursion using your own stack.
The starting point is the following recursive definition:
int sum(int n) {
if (n == 0) return 0;
return n + sum(n - 1);
}
Write a method sumIteratively(int n) that returns the same result.
Model the recursion using a stack: store on the stack the numbers that are "waiting" during the return phase. Use the ArrayDeque implementation for the stack.
You do not yet need a structure such as a Frame object for this exercise.
Implement the calculation of the sum of the nodes in a binary tree containing integers without recursion using your own stack.
Use the following Node class:
public class Node {
int value;
Node left;
Node right;
Node(int value) {
this.value = value;
}
}
The starting point is the following recursive definition:
int sum(Node root) {
if (root == null) return 0;
return root.value + sum(root.left) + sum(root.right);
}
Model the recursion using a stack: each item on the stack represents the state of a recursive call.
For this purpose, you will need a Frame class (for example, containing Node and visited) to maintain the state information. The stack itself does not need to be implemented manually; you may use the ArrayDeque implementation as in the course material.
An example main program is included in the TIM exercise.