In computer programming, the sole purpose of building any software is to solve a problem existing in the real world and make the world a better place to live in. When we talk about a solution to a problem, it's obvious that we're talking about the procedure to be followed to solve the problem.
Let's consider a case where your teacher comes to you and gives you a bunch of candy, asking you to distribute it equally among your classmates. If you consider this as a problem and try to achieve it with ease, then you might do it as follows:
As you can see, I've created six steps to solve the task. You might solve it in a different way. These steps are what we call algorithms in computer science.
So, in a nutshell, we can define algorithms as something that takes a value or a set of values as input, processes it, and returns a value or a set of values as output. In other words, we can say that algorithms are a solution to a well-defined computational problem.
In this book, we'll cover the most commonly used basic algorithms, for example, sorting algorithms, searching algorithms, hashing algorithms, and so on.
Let's look at some examples to understand algorithms. Consider the following code:
private fun add(x: Int, y: Int) = x + y
Please be sure that you have a basic understanding of Kotlin and its syntax.
In the preceding code snippet, the code accepts two arguments as input and returns their sum as output. It satisfies the definition of the algorithm by taking some input, processing the input, and returning the result. Now, consider the following code:
val hourInMillis = 24 * 60 * 60 * 1000
In the preceding example, we can still argue that this is an algorithm. Here, the compiler takes 24, 60, 60, and 1000 as input and multiplies all of them to get the single output and finally assigns the output back to the property named hoursInMillis. Even though this type of code has nothing to do with the runtime, we can define this as a compile-time algorithm.
So, in conclusion, we can say that programs that solve complex computation problems aren't the only programs that can be called algorithms. Instead, any program (whether simple or complex), if that consumes some input to calculate and gives some output can be called as an algorithm. For example, sorting and searching aren't the only processes that can be called algorithms; even a simple assignment can also be treated as an algorithm.
This is the beauty of computer science theory. There's no single definition available for algorithms. We just have a few rules to categorize something as an algorithm. As long as your program satisfies those, we can argue that it's an algorithm.
We solved the previous example by taking a few steps, such as asking all students to stand in a queue and, once a student got candy, we moved them to a separate group. We could have also done the same task without asking them to maintain a queue or separating them into a separate group once they got the candy. But we did that to make the task go smoother. Of course, we could have done the task without these two sub-tasks, but that would have created a lot of confusion and made it tedious to finish the task on time.
If we consider that example, we can treat candies and students as data. And to solve the problem given by the teacher, we first structured the data and solved it with ease. This is what we call data structures in computer science.
In this book, we'll cover the most commonly used data structures such as an array, string, list, linked list, stack, queue, tree, graph, and so on. The order isn't the same though. If we talk about data structures in front of others, people generally think about the earlier mentioned data structures. But this doesn't mean that these are the only data structures available. We've a lot more data structures available and ones that are commonly used. In addition to these commonly used data structures, we can also define our own data structures based on our business needs. We might customize data structures in two ways:
- Extend existing data structures
- Customize data structures
If we've a problem, that can be achieved with the help of list but with a slight modification, then we'll try to extend the existing List class present in Kotlin's collection framework instead of creating a completely new data structure. For example, the problem statement says to have a list of names, only in uppercase. Of course, there's no existing data structure that can do this out of the box. So you need to extend the List and modify it a bit as per our need. So that all existing functionality of List gets inherited and works the same as earlier, except with the modified one. Let's see the code:
class UpperCasedList : ArrayList<S...