Encode given string by replacing substrings with prefix same as itself with *

• Difficulty Level : Medium
• Last Updated : 29 Dec, 2021

Given string str of size N containing only lowercase English letters. The task is to encrypt the string such that the substrings having same prefix as itself are replaced by a *. Generate the encrypted string.

Note: If the string can be encrypted in multiple ways, find the smallest encrypted string.

Examples:

Input: str = “ababcababcd”
Output: ab*c*d
Explanation: The substring “ababc” starting from 5th index (0 based indexing) can be replaced by a ‘*’. So the string becomes “ababcababcd” ->  “ababc*d”. Now the substring “ab” starting from 2nd index can again be replaced with a ‘*’. So the string becomes “ab*c*d”

Input: str = “zzzzzzz”
Output: z*z*z
Explanation: The string can be encrypted  in 2 ways: “z*z*z” and “z**zzz”. Out of  the two “z*z*z” is smaller in length.

Approach: A simple solution to generate smallest encrypted string is to find the longest non-overlapping repeated substring and encrypt that substring first. To implement this use the following steps:

• Create a stack to store the encrypted string.
• Declare two pointers (i & j) to point to the 1st index and middle index respectively.
• Now start traversing the string and repeat the loop until the entire string is scanned. Follow steps mentioned below for each iteration:
• Compare both the substring from index i and j.
• If both substrings are equal, then repeat the same process on this substring and store the remaining string into stack.
• Else decrement the value of 2nd pointer ( j ) by 1.
• Now pop all the elements from the stack and append a symbol “*” then store it in a output string.
• Return the encrypted string.

Below is the implementation of the above approach.

C++

 `// C++ code to implement the above approach``#include ``using` `namespace` `std;`` ` `// Function to generate the encrypted string``string compress(string str)``{``    ``// Stack to store encrypted string``    ``stack st;`` ` `    ``// Variable to store length of string``    ``int` `N = str.length();`` ` `    ``// Variable to point 1st and middle index``    ``int` `i = 0, j = N / 2;`` ` `    ``// Repeat the loop until``    ``// the entire string is checked``    ``while` `(j > 0) {``        ``int` `mid = j;`` ` `        ``// Compare the substring``        ``// from index 0 to mid-1``        ``// with the rest of the substring``        ``// after mid.``        ``for` `(i = 0; i < mid && str[i] == str[j]; i++, j++)``            ``;`` ` `        ``// If both substrings are equal``        ``// then repeat the same process``        ``// on this substring and store``        ``// the remaining string into stack``        ``if` `(i == mid) {``            ``st.push(str.substr(j, N - 1));`` ` `            ``// Update the value of``            ``// string 'str' with the``            ``// longest repeating substring``            ``str = str.substr(0, i);`` ` `            ``// Set the new string length to n``            ``N = mid;`` ` `            ``// Initialize the 2nd pointer``            ``// from the mid of new string``            ``j = N / 2;``        ``}`` ` `        ``// If both substrings are not equal``        ``// then decrement the 2nd pointer by 1``        ``else` `{``            ``j = mid - 1;``        ``}``    ``}`` ` `    ``// Pop all the elements from the stack``    ``// append a symbol '*' and store``    ``// in a output string``    ``while` `(!st.empty()) {``        ``str = str + ``"*"` `+ st.top();``        ``st.pop();``    ``}`` ` `    ``return` `str;``}`` ` `// Driver code``int` `main()``{``    ``// Declare and initialize the string``    ``string str = ``"zzzzzzz"``;`` ` `    ``cout << compress(str) << ``"\n"``;``    ``return` `0;``}`

Java

 `// Java code to implement the above approach`` ` `import` `java.util.*;`` ` `class` `GFG{`` ` `// Function to generate the encrypted String``static` `String compress(String str)``{``    ``// Stack to store encrypted String``    ``Stack st = ``new` `Stack();`` ` `    ``// Variable to store length of String``    ``int` `N = str.length();`` ` `    ``// Variable to point 1st and middle index``    ``int` `i = ``0``, j = N / ``2``;`` ` `    ``// Repeat the loop until``    ``// the entire String is checked``    ``while` `(j > ``0``) {``        ``int` `mid = j;`` ` `        ``// Compare the subString``        ``// from index 0 to mid-1``        ``// with the rest of the subString``        ``// after mid.``        ``for` `(i = ``0``; i < mid && str.charAt(i) == str.charAt(j); i++, j++)``            ``;`` ` `        ``// If both subStrings are equal``        ``// then repeat the same process``        ``// on this subString and store``        ``// the remaining String into stack``        ``if` `(i == mid) {``            ``st.add(str.substring(j,  N));`` ` `            ``// Update the value of``            ``// String 'str' with the``            ``// longest repeating subString``            ``str = str.substring(``0``, i);`` ` `            ``// Set the new String length to n``            ``N = mid;`` ` `            ``// Initialize the 2nd pointer``            ``// from the mid of new String``            ``j = N / ``2``;``        ``}`` ` `        ``// If both subStrings are not equal``        ``// then decrement the 2nd pointer by 1``        ``else` `{``            ``j = mid - ``1``;``        ``}``    ``}`` ` `    ``// Pop all the elements from the stack``    ``// append a symbol '*' and store``    ``// in a output String``    ``while` `(!st.isEmpty()) {``        ``str = str + ``"*"` `+ st.peek();``        ``st.pop();``    ``}`` ` `    ``return` `str;``}`` ` `// Driver code``public` `static` `void` `main(String[] args)``{``    ``// Declare and initialize the String``    ``String str = ``"zzzzzzz"``;`` ` `    ``System.out.print(compress(str)+ ``"\n"``);``}``}`` ` `// This code is contributed by 29AjayKumar`

Python3

 `# Python code for the above approach`` ` `# Function to generate the encrypted string``def` `compress(``str``):`` ` `    ``# Stack to store encrypted string``    ``st ``=` `[]`` ` `    ``# Variable to store length of string``    ``N ``=` `len``(``str``)`` ` `    ``# Variable to point 1st and middle index``    ``i ``=` `0``    ``j ``=` `(``int``)(N ``/` `2``)`` ` `    ``# Repeat the loop until``    ``# the entire string is checked``    ``while` `(j > ``0``):``        ``mid ``=` `j`` ` `        ``# Compare the substring``        ``# from index 0 to mid-1``        ``# with the rest of the substring``        ``# after mid.``        ``i``=``0``        ``while``(``str``[i] ``=``=` `str``[j] ``and` `i < mid):``            ``i ``+``=` `1``            ``j ``+``=` `1``        ``# If both substrings are equal``        ``# then repeat the same process``        ``# on this substring and store``        ``# the remaining string into stack``        ``if` `(i ``=``=` `mid):``            ``st.append(``str``[j:N])`` ` `            ``# Update the value of``            ``# string 'str' with the``            ``# longest repeating substring``            ``str` `=` `str``[``0``:i]`` ` `            ``# Set the new string length to n``            ``N ``=` `mid`` ` `            ``# Initialize the 2nd pointer``            ``# from the mid of new string``            ``j ``=` `N ``/``/` `2`` ` `        ``# If both substrings are not equal``        ``# then decrement the 2nd pointer by 1``        ``else``:``            ``j ``=` `mid ``-` `1`` ` `    ``# Pop all the elements from the stack``    ``# append a symbol '*' and store``    ``# in a output string``    ``while` `(``len``(st) !``=` `0``):``        ``str` `=` `str` `+` `'*'` `+` `st[``len``(st) ``-` `1``]``        ``st.pop()``    ``return` `str`` ` `# Driver code`` ` `# Declare and initialize the string``str` `=` `"zzzzzzz"``print``(compress(``str``))`` ` `# This code is contributed by Saurabh jaiswal`

C#

 `// C# code to implement the above approach``using` `System;``using` `System.Collections.Generic;`` ` `public` `class` `GFG{`` ` `// Function to generate the encrypted String``static` `String compress(String str)``{``    ``// Stack to store encrypted String``    ``Stack st = ``new` `Stack();`` ` `    ``// Variable to store length of String``    ``int` `N = str.Length;`` ` `    ``// Variable to point 1st and middle index``    ``int` `i = 0, j = N / 2;`` ` `    ``// Repeat the loop until``    ``// the entire String is checked``    ``while` `(j > 0) {``        ``int` `mid = j;`` ` `        ``// Compare the subString``        ``// from index 0 to mid-1``        ``// with the rest of the subString``        ``// after mid.``        ``for` `(i = 0; i < mid && str[i] == str[j]; i++, j++)``            ``;`` ` `        ``// If both subStrings are equal``        ``// then repeat the same process``        ``// on this subString and store``        ``// the remaining String into stack``        ``if` `(i == mid) {``            ``st.Push(str.Substring(j,  N-j));`` ` `            ``// Update the value of``            ``// String 'str' with the``            ``// longest repeating subString``            ``str = str.Substring(0, i);`` ` `            ``// Set the new String length to n``            ``N = mid;`` ` `            ``// Initialize the 2nd pointer``            ``// from the mid of new String``            ``j = N / 2;``        ``}`` ` `        ``// If both subStrings are not equal``        ``// then decrement the 2nd pointer by 1``        ``else` `{``            ``j = mid - 1;``        ``}``    ``}`` ` `    ``// Pop all the elements from the stack``    ``// append a symbol '*' and store``    ``// in a output String``    ``while` `(st.Count!=0) {``        ``str = str + ``"*"` `+ st.Peek();``        ``st.Pop();``    ``}`` ` `    ``return` `str;``}`` ` `// Driver code``public` `static` `void` `Main(String[] args)``{``    ``// Declare and initialize the String``    ``String str = ``"zzzzzzz"``;`` ` `    ``Console.Write(compress(str)+ ``"\n"``);``}``}`` ` `// This code is contributed by shikhasingrajput`

Javascript

 ``

Output
`z*z*z`

Time Complexity: O(N. Log(N))
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up