📌  相关文章
📜  用给定的字符串包装给定单词的每个连续实例

📅  最后修改于: 2021-05-06 03:29:52             🧑  作者: Mango

给定两个字符串S1S2 。任务是将字符串S2的每个实例包装在字符串S1中,并在任一侧带有一些字符串。
注意:在这里,我们将下划线(_)用于包装部分。根据需要可以是任何东西,例如一些HTML标记,空白等。
例子:

方法:想法是简单地获取字符串S2的所有实例在S1中的位置,并在事件的任一端添加下划线,如果两个或多个S2实例重叠,则在合并的子字符串的任一端添加下划线。步骤如下:

  1. 获取字符串S2的所有实例在主字符串S1中的位置。对于该遍历字符串S1,一次一个字符,并调用子字符串匹配函数find()。
  2. 创建一个二维位置数组(例如arr [] [] ),其中每个子数组都包含字符串S1中字符串S2的特定实例的开始和结束索引。
  3. 合并存储在arr [] []中的重叠的开始和结束索引间隔。
  4. 完成上述步骤后,所有重叠的索引将合并。现在,同时遍历给定的字符串和间隔,并通过包装下划线创建一个新的字符串。
  5. 在上述步骤之后打印新的字符串。

下面是上述方法的实现:

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的长度