A data structure determines how data is organized so that information can be used efficiently. Each data structure supports some operations efficiently, while other operations are either inefficient or not supported at all. Since different operations are supported by each data structure, you should carefully evaluate which data structure will work best for your particular problem.
C++
The C++
standard library data structures are
designed to store any type of data. We put the desired data type within the <>
brackets when declaring the data structure, as follows:
vector<string> v;
This creates a vector structure that only stores objects of type string.
For our examples below, we will primarily use the int data type, but note that
you can use any data type including string and user-defined structures.
Nearly every standard library data structure supports the size() method, which
returns the number of elements in the data structure, and the empty() method,
which returns true if the data structure is empty, and false otherwise.
Java
Python
Lists
The default way to store data in Python is using a list, which can automatically resize itself to accommodate more elements. We can add and delete elements at the end in time. A list can be initialized as follows:
arr = []
Python lists are generic. This means that they can store any kind of data type, including objects. For example, the following code creates a dynamic array and adds the numbers through to it:
for i in range(1, 11): # Note that range(i, j) includes i, but does not include jarr.append(i)
In Python, we can give a dynamic array an initial size. The code below creates a dynamic array with zeroes.
arr = [0] * 30
Iterating
We can use a regular for loop to iterate through all elements of a list.
arr = [1, 7, 4, 5, 2]for i in range(len(arr)):print(arr[i], end=" ")print()for element in arr:print(element, end=" ")print()
We can also use iterators. An iterator allows you to traverse a container by
pointing to an object within the container. iter(arr) returns an iterator
pointing to the first element of the list arr.
arr = [4, 2, 0, 0, 5]it = iter(arr)print(next(it)) # 4print(next(it)) # 2print(next(it)) # 0
Inserting and Erasing
arr = []arr.append(2) # [2]arr.append(3) # [2, 3]arr.append(7) # [2, 3, 7]arr.append(5) # [2, 3, 7, 5]arr[1] = 4# sets element at index 1 to 4 -> [2, 4, 7, 5]arr.pop(1) # removes element at index 1 -> [2, 7, 5]# this remove method is O(n); to be avoidedarr.append(8) # [2, 7, 5, 8]
List Comprehensions
List comprehensions are extremely useful for simplifying a python for loop that
modifies/creates a list into one expression. The general syntax is:
[ expression for item in list if conditional ]
An example is provided in the code block below.
# If a number is odd, add the number times 2 into the arrayold_list = [2, 5, 3, 1, 6]new_list = []for i in old_list:if i % 2 == 1:new_list.append(i * 2)print(new_list) # [10, 6, 2]# Simplified one liner with list comprehension# Recall the form [ expression for item in list if conditional ]# expression: i * 2# list: old_list# conditional: i % 2 == 1 (only include item i if it satisfies the conditional)new_list = [i * 2 for i in old_list if i % 2 == 1]print(new_list) # [10, 6, 2]
A very applicable use of list comprehensions for competitive programming in particular is creating an integer list from space separated input:
# Example input: 5 3 2 6 8 1# Note that the conditional in the list comprehension is optional, and defaults to True if not providedarr = [int(x) for x in input().split()]print(arr) # [5, 3, 2, 6, 8, 1]
For more information on list comprehensions, including nesting them to create multidimensional lists, refer to the below resources.
| Resources | |||||
|---|---|---|---|---|---|
| PythonForBeginners | Basic list comprehension tutorial | ||||
| GFG | Nesting list comprehensions | ||||
Pairs
If we want to store a collection of points on the 2D plane, then we can use a dynamic array of pairs.
While Python doesn't have a specific class just for pairs, 2-element tuples give nearly the exact same functionality. The only issue is that you can't modify the elements since tuples are immutable.
On the other hand, Python has built-in comparison support for tuples. When comparing, it looks at the first elements of each pair, then the second, and so on and so forth.
"""Output:(5, 'asdf')5True"""p1 = (5, "asdf")print(p1)print(p1[0]) # access the first element of the tuplep2 = (6, "asdf")print(p1 < p2)
Memory Allocation
One thing to keep in mind when using arrays is the memory limit. Usually the USACO memory limit is 256 MB. To estimate how many values can be stored within this limit:
- Calculate the total memory size in bytes: for 256 MB, that's .
- Divide by the size, in bytes, of an
int(4), or along long(8), etc. For example, the number ofints that you are able to store is bounded above by . - Be aware that program overhead (which can be very significant, especially with recursive functions) will reduce the amount of memory available.
Quiz
How do you count the number of items in a list? Suppose we named the list l.
Problems
Nothing to see here! To reiterate, arrays of fixed size should suffice for essentially every Bronze problem, but dynamic arrays, pairs, and tuples can greatly simplify implementation at times. You'll see some examples of these in the following module.
Module Progress:
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!