给定两个字符串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_”
方法:想法是简单地获取S1中字符串S2的所有实例的位置,并在出现的任一端添加下划线,如果S2 的两个或多个实例重叠,则在合并的子字符串的任一端添加下划线。以下是步骤:
- 获取主字符串S1 中字符串S2的所有实例的位置。对于该遍历字符串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 的长度
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live