给定两个字符串S1和S2 。任务是将字符串S2的每个实例包装在字符串S1中,并在任一侧带有一些字符串。
注意:在这里,我们将下划线(_)用于包装部分。根据需要可以是任何东西,例如一些HTML标记,空白等。
例子:
Input: S1 = “examwill be a examexam”, S2 = “exam”
Output: “_exam_will be a _examexam_”
Explanation:
String S2 is “exam“, so wrap occurrence of S2 with underscore. Since, last two occurance overlaps(in string examexam), so merge both the occurrence and wrap by putting underscore to farther left and farther right of merged substring.
Input: str = “abcabcabcabc”, substr = “abc”
Output: “_abcabcabcabc_”
方法:想法是简单地获取字符串S2的所有实例在S1中的位置,并在事件的任一端添加下划线,如果两个或多个S2实例重叠,则在合并的子字符串的任一端添加下划线。步骤如下:
- 获取字符串S2的所有实例在主字符串S1中的位置。对于该遍历字符串S1,一次一个字符,并调用子字符串匹配函数find()。
- 创建一个二维位置数组(例如arr [] [] ),其中每个子数组都包含字符串S1中字符串S2的特定实例的开始和结束索引。
- 合并存储在arr [] []中的重叠的开始和结束索引间隔。
- 完成上述步骤后,所有重叠的索引将合并。现在,同时遍历给定的字符串和间隔,并通过包装下划线创建一个新的字符串。
- 在上述步骤之后打印新的字符串。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function Definations
vector > getLocations(string str,
string subStr);
vector > collapse(
vector > locations);
string underscorify(string str,
vector > locations);
// Function that creates the string by
// wrapping the underscore
string underscorifySubstring(string str,
string subStr)
{
// Function Call to intervals of
// starting and ending index
vector > locations
= collapse(getLocations(str, subStr));
// Function Call
return underscorify(str, locations);
}
// Function finds all starting and ending
// index of the substring in given string
vector > getLocations(string str,
string subStr)
{
vector > locations{};
int startIdx = 0;
int L = subStr.length();
// Traverse string str
while (startIdx < str.length()) {
// Find substr
int nextIdx = str.find(subStr,
startIdx);
// If location found, then insert
// pair int location[]
if (nextIdx != string::npos) {
locations.push_back({ nextIdx,
(nextIdx + L) });
// Update the start index
startIdx = nextIdx + 1;
}
else {
break;
}
}
return locations;
}
// Function to merge the locations
// of substrings that overlap each
// other or sit next to each other
vector > collapse(
vector > locations)
{
if (locations.empty()) {
return locations;
}
// 2D vector to store the merged
// location of substrings
vector > newLocations{ locations[0] };
vector* previous = &newLocations[0];
for (int i = 1; i < locations.size(); i++) {
vector* current = &locations[i];
// Condition to check if the
// substring overlaps
if (current->at(0) <= previous->at(1)) {
previous->at(1) = current->at(1);
}
else {
newLocations.push_back(*current);
previous
= &newLocations[newLocations.size() - 1];
}
}
return newLocations;
}
// Function creates a new string with
// underscores added at correct positions
string underscorify(string str,
vector > locations)
{
int locationsIdx = 0;
int stringIdx = 0;
bool inBetweenUnderscores = false;
vector finalChars{};
int i = 0;
// Traverse the string and check
// in locations[] to append _
while (stringIdx < str.length()
&& locationsIdx < locations.size()) {
if (stringIdx
== locations[locationsIdx][i]) {
// Insert underscore
finalChars.push_back("_");
inBetweenUnderscores
= !inBetweenUnderscores;
// Increment location index
if (!inBetweenUnderscores) {
locationsIdx++;
}
i = i == 1 ? 0 : 1;
}
// Create string s
string s(1, str[stringIdx]);
// Push the created string
finalChars.push_back(s);
stringIdx++;
}
if (locationsIdx < locations.size()) {
finalChars.push_back("_");
}
else if (stringIdx < str.length()) {
finalChars.push_back(str.substr(stringIdx));
}
// Return the resultant string
return accumulate(finalChars.begin(),
finalChars.end(), string());
}
// Driver Code
int main()
{
// Given string S1 and S2
string S1 = "examwill be a examexam";
string S2 = "exam";
// Function Call
cout << underscorifySubstring(S1, S2);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG
{
// Function that creates the string by
// wrapping the underscore
static String underscorifySubstring(String str,
String subStr)
{
// Function Call to intervals of
// starting and ending index
List > locations
= collapse(getLocations(str, subStr));
// Function Call
return underscorify(str, locations);
}
// Function finds all starting and ending
// index of the substring in given string
static List > getLocations(String str,
String subStr)
{
@SuppressWarnings("unchecked")
List > locations = new ArrayList();
int startIdx = 0;
int L = subStr.length();
// Traverse string str
while (startIdx < str.length())
{
// Find substr
int nextIdx = str.indexOf(subStr, startIdx);
// If location found, then insert
// pair int location[]
if (nextIdx != -1)
{
locations.add(Arrays.asList(new Integer[] {
nextIdx, nextIdx + L }));
// Update the start index
startIdx = nextIdx + 1;
}
else
{
break;
}
}
return locations;
}
// Function to merge the locations
// of substrings that overlap each
// other or sit next to each other
static List >
collapse(List > locations)
{
if (locations.size() == 0)
{
return locations;
}
// 2D vector to store the merged
// location of substrings
@SuppressWarnings("unchecked")
List > newLocations = new ArrayList();
newLocations.add(locations.get(0));
List previous = locations.get(0);
for (int i = 1; i < locations.size(); i++)
{
List current = locations.get(i);
// Condition to check if the
// substring overlaps
if (current.get(0) <= previous.get(1))
{
previous.set(1, current.get(1));
}
else
{
newLocations.add(current);
previous = newLocations.get(
newLocations.size() - 1);
}
}
return newLocations;
}
// Function creates a new string with
// underscores added at correct positions
static String
underscorify(String str, List > locations)
{
int locationsIdx = 0;
int stringIdx = 0;
boolean inBetweenUnderscores = false;
StringBuilder finalChars = new StringBuilder();
int i = 0;
// Traverse the string and check
// in locations[] to append _
while (stringIdx < str.length()
&& locationsIdx < locations.size()) {
if (stringIdx
== locations.get(locationsIdx).get(i)) {
// Insert underscore
finalChars.append("_");
inBetweenUnderscores
= !inBetweenUnderscores;
// Increment location index
if (!inBetweenUnderscores)
{
locationsIdx++;
}
i = i == 1 ? 0 : 1;
}
// Push the string
finalChars.append(str.charAt(stringIdx));
stringIdx++;
}
if (locationsIdx < locations.size()) {
finalChars.append("_");
}
else if (stringIdx < str.length()) {
finalChars.append(str.substring(stringIdx));
}
// Return the resultant string
return finalChars.toString();
}
public static void main(String[] args)
{
// Given string S1 and S2
String S1 = "examwill be a examexam";
String S2 = "exam";
// Function Call
System.out.print(underscorifySubstring(S1, S2));
}
}
// This code is contributed by jithin
_exam_will be a _examexam_
时间复杂度: O(N * M),其中N和M分别是字符串S1和S2的长度。
辅助空间: O(N),其中N是字符串S1的长度