Encode given string by replacing substrings with prefix same as itself with *
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++
#include <bits/stdc++.h>
using namespace std;
string compress(string str)
{
stack<string> st;
int N = str.length();
int i = 0, j = N / 2;
while (j > 0) {
int mid = j;
for (i = 0; i < mid && str[i] == str[j]; i++, j++)
;
if (i == mid) {
st.push(str.substr(j, N - 1));
str = str.substr(0, i);
N = mid;
j = N / 2;
}
else {
j = mid - 1;
}
}
while (!st.empty()) {
str = str + "*" + st.top();
st.pop();
}
return str;
}
int main()
{
string str = "zzzzzzz" ;
cout << compress(str) << "\n" ;
return 0;
}
|
Java
import java.util.*;
class GFG{
static String compress(String str)
{
Stack<String> st = new Stack<String>();
int N = str.length();
int i = 0 , j = N / 2 ;
while (j > 0 ) {
int mid = j;
for (i = 0 ; i < mid && str.charAt(i) == str.charAt(j); i++, j++)
;
if (i == mid) {
st.add(str.substring(j, N));
str = str.substring( 0 , i);
N = mid;
j = N / 2 ;
}
else {
j = mid - 1 ;
}
}
while (!st.isEmpty()) {
str = str + "*" + st.peek();
st.pop();
}
return str;
}
public static void main(String[] args)
{
String str = "zzzzzzz" ;
System.out.print(compress(str)+ "\n" );
}
}
|
Python3
def compress( str ):
st = []
N = len ( str )
i = 0
j = ( int )(N / 2 )
while (j > 0 ):
mid = j
i = 0
while ( str [i] = = str [j] and i < mid):
i + = 1
j + = 1
if (i = = mid):
st.append( str [j:N])
str = str [ 0 :i]
N = mid
j = N / / 2
else :
j = mid - 1
while ( len (st) ! = 0 ):
str = str + '*' + st[ len (st) - 1 ]
st.pop()
return str
str = "zzzzzzz"
print (compress( str ))
|
C#
using System;
using System.Collections.Generic;
public class GFG{
static String compress(String str)
{
Stack<String> st = new Stack<String>();
int N = str.Length;
int i = 0, j = N / 2;
while (j > 0) {
int mid = j;
for (i = 0; i < mid && str[i] == str[j]; i++, j++)
;
if (i == mid) {
st.Push(str.Substring(j, N-j));
str = str.Substring(0, i);
N = mid;
j = N / 2;
}
else {
j = mid - 1;
}
}
while (st.Count!=0) {
str = str + "*" + st.Peek();
st.Pop();
}
return str;
}
public static void Main(String[] args)
{
String str = "zzzzzzz" ;
Console.Write(compress(str)+ "\n" );
}
}
|
Javascript
<script>
function compress(str)
{
let st = [];
let N = str.length;
let i = 0, j = Math.floor(N / 2);
while (j > 0) {
let mid = j;
for (i = 0; i < mid && str[i] == str[j]; i++, j++)
;
if (i == mid) {
st.push(str.slice(j, N));
str = str.slice(0, i);
N = mid;
j = Math.floor(N / 2);
}
else {
j = mid - 1;
}
}
while (st.length != 0) {
str = str + '*' + st[st.length - 1];
st.pop();
}
return str;
}
let str = "zzzzzzz" ;
document.write(compress(str) + '<br>' );
</script>
|
Time Complexity: O(N. Log(N))
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...