Lesson 4
String Manipulation in C#: Finding Substring Occurrences
Introduction

Hello, and welcome to our analysis lesson. Today, we will explore a classic problem in the realm of string manipulations. We'll learn how to locate all occurrences of a substring within a larger string using C#. The techniques you will learn can be used in scenarios such as text processing and data analysis. Are you ready to dive in? Let's get started!

Task Statement and Description

Here's our challenge: we have two lists of strings of the same length, one containing the "original" strings and the other, the "substrings." We're to identify all occurrences of each substring within its corresponding original string and return a list of the starting indices of these occurrences. Remember, index counting should start from 0.

Example

If we take the following lists:
Original List: new List<string> { "HelloWorld", "LearningCSharp", "GoForBroke", "BackToBasics" }
Substring List: new List<string> { "loW", "ear", "o", "Ba" }.

This will produce the following outputs:
In "HelloWorld", "loW" starts at index 3.
In "LearningCSharp", "ear" starts at index 1.
In "GoForBroke", "o" appears at indices 1, 3, and 7.
In "BackToBasics", "Ba" starts at indices 0 and 6.

So, if FindSubString(new List<string> { "HelloWorld", "LearningCSharp", "GoForBroke", "BackToBasics" }, new List<string> { "loW", "ear", "o", "Ba" }) is called, the function should return:

1[ 2 "The substring 'loW' was found in the original string 'HelloWorld' at position(s) 3.", 3 "The substring 'ear' was found in the original string 'LearningCSharp' at position(s) 1.", 4 "The substring 'o' was found in the original string 'GoForBroke' at position(s) 1, 3, 7.", 5 "The substring 'Ba' was found in the original string 'BackToBasics' at position(s) 0, 6." 6]

Although this task seems reasonably straightforward, it may still feel daunting. Fear not! We will dissect it piece by piece.

Step-by-Step Solution: Initializing the Output

First, we need to create a place to store the result of our findings. Can you think of a C# data type that we could use for that? That's correct — a List<string> would be perfect for this task!

C#
1public static List<string> Solution(List<string> origStrs, List<string> substrs) 2{ 3 List<string> resultArr = new List<string>(); 4}
Pairing Strings and Finding First Occurrence

We iterate over the pairs of original strings and substrings using a simple for loop. We then use the IndexOf() method to find the first occurrence of each substring in its related original string. C# string objects have a built-in method called str.IndexOf(substring, startingIndex) which returns the first index position of the substring starting from startingIndex, if found. Otherwise, it returns -1.

C#
1for (int i = 0; i < origStrs.Count; i++) 2{ 3 string original = origStrs[i]; 4 string substring = substrs[i]; 5 int startPos = original.IndexOf(substring); 6}

In original.IndexOf(substring), we pass the substring that we want to locate. The function begins the search from the beginning as we have not specified a starting position.

Finding Subsequent Occurrences

The following step is to locate the rest of the instances of the substring in the original.

We use a while loop to accomplish this. But, how will we know when to stop seeking more occurrences? Good question! The moment our .IndexOf() function returns -1, it signifies that there are no more matches to be found.

Each time we find a match, we append its starting index to the matchIndices list and adjust the startPos to search after the end of this match:

C#
1 List<string> matchIndices = new List<string>(); 2 while (startPos != -1) 3 { 4 matchIndices.Add(startPos.ToString()); 5 startPos = original.IndexOf(substring, startPos + 1); 6 }
Formatting and Storing the Results

Finally, we format the result for readability and append it to the resultArr:

C#
1{ 2 resultArr.Add($"The substring '{substring}' was found in the original string '{original}' at position(s) {string.Join(", ", matchIndices)}."); 3}

With this, we've come to the end of our method design.

The Final Solution

Here is the comprehensive solution, which incorporates all the steps above:

C#
1using System; 2using System.Collections.Generic; 3 4public class Program 5{ 6 public static List<string> Solution(List<string> origStrs, List<string> substrs) 7 { 8 List<string> resultArr = new List<string>(); 9 10 for (int i = 0; i < origStrs.Count; i++) 11 { 12 string original = origStrs[i]; 13 string substring = substrs[i]; 14 int startPos = original.IndexOf(substring); 15 List<string> matchIndices = new List<string>(); 16 17 while (startPos != -1) 18 { 19 matchIndices.Add(startPos.ToString()); 20 startPos = original.IndexOf(substring, startPos + 1); 21 } 22 23 resultArr.Add($"The substring '{substring}' was found in the original string '{original}' at position(s) {string.Join(", ", matchIndices)}."); 24 } 25 26 return resultArr; 27 } 28 29 public static void Main() 30 { 31 List<string> originalList = new List<string> { "HelloWorld", "LearningCSharp", "GoForBroke", "BackToBasics" }; 32 List<string> substringList = new List<string> { "loW", "ear", "o", "Ba" }; 33 List<string> results = Solution(originalList, substringList); 34 35 foreach (var result in results) 36 { 37 Console.WriteLine(result); 38 // Expected Output: 39 // The substring 'loW' was found in the original string 'HelloWorld' at position(s) 3. 40 // The substring 'ear' was found in the original string 'LearningCSharp' at position(s) 1. 41 // The substring 'o' was found in the original string 'GoForBroke' at position(s) 1, 3, 7. 42 // The substring 'Ba' was found in the original string 'BackToBasics' at position(s) 0, 6. 43 } 44 } 45}
Lesson Summary

Congratulations! You've mastered a vital operation in string manipulations — finding all occurrences of a substring in another string using C#. Remember, this algorithm has numerous applications in real-world scenarios. Now that we have thoroughly dissected and examined a systematic way to handle it, I encourage you to practice further. Upcoming exercises will provide an opportunity for you to refine your skills better. Keep on coding and learning!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.