Lecture 14
Lecture 14
Spring 2024
Lecture 14:
- More about {arrays, structs, strings}
Instructor: Preethi Jyothi
- Based on material developed by Prof. Abhiram Ranade and Prof. Manoj Prabhakaran
Recap: Lexicographically compare two strings
int compare(char A[], char B[]) {
int i = 0;
while(true) {
if(A[i] == '\0' && B[i] == '\0') return 0;
if(A[i] == '\0') return -1;
if(B[i] == '\0') return 1;
if(A[i] < B[i]) return -1; Takes two strings A, B
and returns 0 if they are
if(A[i] > B[i]) return 1;
equal, 1 if A is
i++; lexicographically greater
} than B and -1 otherwise.
}
int main() {
char A[30], B[30];
cin.getline(A,30); cin.getline(B,30);
cout << A << " " << B << " " << compare(A,B) << endl;
}
Recap int compare(char A[], char B[]) {
int i = 0;
while(true) {
What is the output of the following program? if(A[i] == '\0' && B[i] == '\0') return 0;
if(A[i] == '\0') return -1;
main_program { if(B[i] == '\0') return 1;
char c1[20] = "hello"; if(A[i] < B[i]) return -1;
char c2[] = {'h','e','l','l','o'}; if(A[i] > B[i]) return 1;
i++;
}
if(!compare(c1,c2)) }
cout << "c1=c2"; A c1=c2
else if(compare(c1,c2) == 1)
cout << "c1>c2"; B c1>c2
else
cout << "c1<c2"; c1<c2
C
}
c1 is automatically terminated with a '\0', while c2 isn't. Note that the assignment
operator cannot be used again once a string is initialized. c1 = "world"; after char
c1[20] = "hello"; will result in a compiler error.
Merge sort
CS 101, 2025
Divide-and-Conquer
• Some algorithms use a Divide-and-Conquer strategy
(a.k.a. Divide-Conquer-and-Combine)
resultType f(inputType x) {
• A problem instance is divided into
two or more smaller problems if (baseCase(x))
return handleBaseCase(x);
• The smaller instances are solved
recursively inputType x1, x2;
Divide(x,x1,x2);
• The results are then combined to get
the result for the original instance resultType y1, y2;
• An example: Merge Sort y1 = f(x1); y2 = f(x2);
return Combine(y1,y2);
}
Merge Sort
• Split into two (almost) equal halves, and recursively sort each half
• Merge the two sorted arrays into a single sorted array
53 46 94 43 17 12 60 98 86 50 36 26 57 80 77 18
Recursively Recursively
sort sort
12 17 43 46 53 60
18 94
26 98
36 50 5
Merge
12 17 18 26 36 43 46 50 53 57 60 77 80 86 94 98
Merge Sort
• Split into two (almost) equal halves, and recursively sort each half
• Merge the two sorted arrays into a single sorted array
53 46 94 43 17 12 60 98 86 50 36 26 57 80 77 18
Recursively Recursively
sort sort
12 17 43 46 53 60
18 94
26 98
36 50 5
Merge
12 17 18 26 36 43 46 50 53 57 60 77 80 86 94 98
12 17 43 46 53 60
18 94
26 98
36 50 5
Merge
12 17 18 26 36 43 46 50 53 57 60 77 80 86 94 98
Merge Sort Output will be in the array out[ ] in
indices left,...,right. A temporary array
scratch[ ] passed as input (since its size is
void sort (const int in[], int out[], not known at compile-time).
int left, int right,
resultType f(inputType x) {
int scratch[]) {
if (baseCase(x))
if (left==right) {
return handleBaseCase(x);
out[left] = in[left];
return;
inputType x1, x2;
}
Divide(x,x1,x2);
int mid = (left+right)/2;
sort(in,scratch,left,mid,out);
resultType y1, y2;
sort(in,scratch,mid+1,right,out);
y1 = f(x1); y2 = f(x2);
merge(scratch,out,left,right);
return Combine(y1,y2);
}
}
More about multidimensional arrays
CS 101, 2025
2D arrays
• Recall matrices can be implemented using 2D arrays. Example:
• countries[i] will return the address of the zeroth character of the ith string in countries
fi
2D arrays
int main() {
char countries[3][20] = {"India", "China", "Sri Lanka"};
char capitals[3][20] = {"New Delhi", "Beijing", "Colombo"};
char country[20];
cout << "Enter country: ";
cin.getline(country, 20);
int i;
for(i = 0; i < 3; i++) {
if(compare(country,countries[i]) == 0) { //compare defined earlier
cout << "Capital -> " << capitals[i] << endl; break;
}
}
if(i == 3) cout << "Do not know the capital\n";
}
Passing two-dimensional arrays to functions
• One can pass a 2D array to a function. However, the second dimension must be given as a
compile-time constant. Example:
• Such a print function can only be used with char arrays where the second dimension is 20
• Can be overcome with more exible array types like vector (coming in later slides)
fl
More about structs
CS 101, 2025
More about structs
• If a struct de nition appears before many functions, it will be visible to all the functions
• Say the parameters of midpoint were ordinary references and not const references. Now
you try to run cout << midpoint(midpoint(p1,p2),p2).y; from main(), as before.
What happens?
• Compiler error!
parameter
structs and member functions
• Functions can be a part of the structure itself. Example:
struct Point {
double x, y;
double length() {
return sqrt(x*x + y*y);
}
double shift(double dx, double dy) {
x+=dx; y+=dy;
}
};
• A member function is called on an object of the struct type using "." notation. Example:
string a = "hello", b = "world", c; Note that you do not need to worry about
the size of the strings, unlike C-style strings
c = a;
getline(cin, a); //to read a line into string a Will read from console into a,
until a newline is encountered
string a = "hello";
int i = a.find("he"); //returns the starting index of the
//first occurrence of "he" within string a
int j = a.find("l", 3); //find starting from index 3
• Comparison expressions <, >, = can be used for strings a, b assuming a lexicographic order
• Lexicographic order: Similar to how words are organized in a dictionary
• Comparison is done character by character, and based on underlying ASCII values
• Example: "hello" < "world", "hello" > "Hello" (ASCII value of h > ASCII value of H)
fi
Dynamic arrays (vector)
CS 101, 2025
Dynamic allocation
1. C-style arrays (inherited from C, you have already learned about these)
• std::vector is arguably the most exible of the three types and has many useful
supporting features
• Unlike[], the at() method also performs bound checking of whether the index lies
vector<char> C;
C.push_back('a'); //adds an element to the end of the vector
C.resize(3,'b'); //the vector becomes {'a', 'b', 'b'}
Value by which the extra elements of the vector are initialized
• A range-based for loop can be used to access the elements of a vector as follows:
for(int x : A)
cout << x << endl;
• Quick way to initialize a vector of size n with all elements having the same value:
vector<int> A(n, 0); // will initialize A with n elements, all = 0
fi
Represent a matrix using vector
int main() {
print(A); //if A is defined as above
}
[Optional]: Finding maximum subarray
Given an array of ints, nd a contiguous subarray with the largest sum and return its sum.
int maxSubArraySum(const vector<int>& nums) {
int maxSum = nums[0];
int maxUntil_i = nums[0];
for (int i = 1; i < nums.size(); i++) {
int x = nums[i];
maxUntil_i = max(x, maxUntil_i + x);
maxSum = max(maxSum, maxUntil_i);
}
return maxSum;
}
int main() {
vector<int> nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
cout << "Maximum subarray sum: " << maxSubArraySum(nums) << endl;
return 0;
}
Reference: https://en.wikipedia.org/wiki/Maximum_subarray_problem
fi