In-place replace multiple occurrences of a pattern
Given a string and a pattern, replace multiple occurrences of a pattern by character ‘X’. The conversion should be in-place and the solution should replace multiple consecutive (and non-overlapping) occurrences of a pattern by a single ‘X’.
String – GeeksForGeeks Pattern – Geeks Output: XforX String – GeeksGeeks Pattern – Geeks Output: X String – aaaa Pattern – aa Output: X String – aaaaa Pattern – aa Output: Xa
The idea is to maintain two index i and j for in-place replacement. Index i always points to next character in the output string. Index j traverses the string and searches for one or more pattern match. If a match is found, we put character ‘X’ at index i and increment index i by 1 and index j by length of the pattern. Index i is increment only once if we find multiple consecutive occurrences of the pattern. If the pattern is not found, we copy current character at index j to index i and increment both i and j by 1. Since pattern length is always more than equal to 1 and replacement is only 1 character long, we would never overwrite unprocessed characters i.e j >= i is invariant.
Implementation:
C++
// C++ program to in-place replace multiple // occurrences of a pattern by character ‘X’ #include <bits/stdc++.h> using namespace std; // returns true if pattern is prefix of str bool compare( char * str, char * pattern) { for ( int i = 0; pattern[i]; i++) if (str[i] != pattern[i]) return false ; return true ; } // Function to in-place replace multiple // occurrences of a pattern by character ‘X’ void replacePattern( char * str, char * pattern) { // If pattern is null or empty string, // nothing needs to be done if (pattern == NULL) return ; int len = strlen (pattern); if (len == 0) return ; int i = 0, j = 0; int count; // for each character while (str[j]) { count = 0; // compare str[j..j+len] with pattern while (compare(str + j, pattern)) { // increment j by length of pattern j = j + len; count++; } // If single or multiple occurrences of pattern // is found, replace it by character 'X' if (count > 0) str[i++] = 'X' ; // copy character at current position j // to position i and increment i and j if (str[j]) str[i++] = str[j++]; } // add a null character to terminate string str[i] = '\0' ; } // Driver code int main() { char str[] = "GeeksforGeeks" ; char pattern[] = "Geeks" ; replacePattern(str, pattern); cout << str; return 0; } |
Python3
# Python3 program to in-place replace multiple # occurrences of a pattern by character ‘X’ # returns true if pattern is prefix of Str def compare( Str , pattern): if ( len ( Str ) ! = len (pattern)): return False for i in range ( len (pattern)): if ( Str [i] ! = pattern[i]): return False return True # Function to in-place replace multiple # occurrences of a pattern by character ‘X’ def replacePattern( Str ,pattern): # If pattern is null or empty String, # nothing needs to be done if (pattern = = ""): return Len = len (pattern) if ( Len = = 0 ): return i, j = 0 , 0 # for each character while (j < len ( Str )): count = 0 # compare Str[j..j+len] with pattern while (compare( Str [j:j + Len ], pattern)): # increment j by length of pattern j = j + Len count + = 1 # If single or multiple occurrences of pattern # is found, replace it by character 'X' if (count > 0 ): Str = Str [ 0 :i] + 'X' + Str [i + 1 :] i + = 1 # copy character at current position j # to position i and increment i and j if (j< len ( Str )): Str = Str [ 0 :i] + Str [j] + Str [i + 1 :] i + = 1 j + = 1 # add a null character to terminate String Str = Str [ 0 :i] return Str # Driver code Str = "GeeksforGeeks" pattern = "Geeks" Str = replacePattern( Str , pattern) print ( Str ) # This code is contributed by shinjanpatra |
Javascript
<script> // JavaScript program to in-place replace multiple // occurrences of a pattern by character ‘X’ // returns true if pattern is prefix of str function compare(str, pattern) { for (let i = 0; i<pattern.length; i++) if (str[i] != pattern[i]) return false ; return true ; } // Function to in-place replace multiple // occurrences of a pattern by character ‘X’ function replacePattern(str,pattern) { // If pattern is null or empty string, // nothing needs to be done if (pattern == "" ) return ; let len = pattern.length; if (len == 0) return ; let i = 0, j = 0; let count; // for each character while (j<str.length) { count = 0; // compare str[j..j+len] with pattern while (compare(str.substring(j,j+len), pattern)) { // increment j by length of pattern j = j + len; count++; } // If single or multiple occurrences of pattern // is found, replace it by character 'X' if (count > 0){ str = str.substring(0,i) + 'X' + str.substring(i+1,) i++ } // copy character at current position j // to position i and increment i and j if (j<str.length){ str = str.substring(0,i) + str[j] + str.substring(i+1,) i++;j++ } } // add a null character to terminate string str = str.substring(0,i); return str; } // Driver code let str = "GeeksforGeeks" ; let pattern = "Geeks" ; str = replacePattern(str, pattern); document.write(str, "</br>" ); // This code is contributed by shinjanpatra </script> |
XforX
Time complexity: O(n*m) where n is length of string and m is length of the pattern.
Auxiliary Space: O(1)
Implementation using STL
The idea of this implementation is to use the STL in-built functions to search for pattern string in main string and then erasing it from the main string
C++
// C++ program to in-place replace multiple // occurrences of a pattern by character ‘X’ #include <bits/stdc++.h> using namespace std; // Function to in-place replace multiple // occurrences of a pattern by character ‘X’ void replacePattern(string str, string pattern) { // making an iterator for string str string::iterator it = str.begin(); // run this loop until iterator reaches end of string while (it != str.end()) { // searching the first index in string str where // the first occurrence of string pattern occurs it = search(str.begin(), str.end(), pattern.begin(), pattern.end()); // checking if iterator is not pointing to end of the // string str if (it != str.end()) { // erasing the full pattern string from that iterator // position in string str str.erase(it, it + pattern.size()); // inserting 'X' at that iterator position str.insert(it, 'X' ); } } // this loop removes consecutive 'X' in string s // Example: GeeksGeeksforGeeks was changed to 'XXforX' // running this loop will change it to 'XforX' for ( int i = 0; i < str.size() - 1; i++) { if (str[i] == 'X' && str[i + 1] == 'X' ) { // removing 'X' at position i in string str str.erase(str.begin() + i); i--; // i-- because one character was deleted // so repositioning i } } cout << str; } // Driver code int main() { string str = "GeeksforGeeks" ; string pattern = "Geeks" ; replacePattern(str, pattern); return 0; } |
XforX
Time Complexity: O(n*m)
Auxiliary Space: O(1)
This article is contributed by Aditya Goel. If you like GeeksforGeeks and would like to contribute, you can also write an article and mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.