通过将前缀与自身相同的子字符串替换为 * 来编码给定的字符串
给定大小为N的字符串str只包含小写英文字母。任务是加密字符串,以便将具有相同前缀的子字符串替换为* 。生成加密字符串。
注意:如果字符串可以通过多种方式加密,请找到最小的加密字符串。
例子:
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.
方法:生成最小加密字符串的简单解决方案是找到最长的非重叠重复子字符串并首先加密该子字符串。要实现这一点,请使用以下步骤:
- 创建一个堆栈来存储加密字符串。
- 声明两个指针(i & j)分别指向第一个索引和中间索引。
- 现在开始遍历字符串并重复循环,直到扫描整个字符串。每次迭代都遵循下面提到的步骤:
- 比较索引i和j的子字符串。
- 如果两个子字符串相等,则对该子字符串重复相同的过程并将剩余的字符串存储到堆栈中。
- 否则将第二个指针( j )的值减 1。
- 现在从堆栈中弹出所有元素并附加一个符号“*” ,然后将其存储在输出字符串中。
- 返回加密字符串。
下面是上述方法的实现。
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
z*z*z
时间复杂度: O(N. Log(N))
辅助空间: O(N)