📌  相关文章
📜  通过添加字符或附加字符串本身来形成字符串的最小移动

📅  最后修改于: 2021-09-17 16:08:32             🧑  作者: Mango

给定一个字符串S,我们需要编写一个程序来检查是否可以通过执行以下任何操作任意次数来构造给定的字符串S。在每个步骤中,我们可以:

  • 在字符串末尾添加任何字符。
  • 或者,将字符串附加到字符串本身。

上述步骤可以应用任意次数。我们需要编写一个程序来打印形成字符串所需的最少步骤。

例子:

Input : aaaaaaaa
Output : 4 
Explanation: move 1: add 'a' to form "a"
move 2: add 'a' to form "aa"
move 3: append "aa" to form "aaaa" 
move 4: append "aaaa" to form "aaaaaaaa" 

Input: aaaaaa
Output: 4 
Explanation: move 1: add 'a' to form "a"
move 2: add 'a' to form "aa"
move 3: add 'a' to form "aaa" 
move 4: append "aaa" to form "aaaaaa" 

Input: abcabca
Output: 5  

解决这个问题的想法是使用动态规划来计算最小移动次数。创建一个大小为 n 的名为dp的数组,其中 n 是输入字符串的长度。 dp[i] 存储生成子串 (0…i) 所需的最小移动次数。根据问题,有两种可能的移动:

  1. dp[i] = min(dp[i], dp[i-1] + 1)表示添加字符。
  2. dp[i*2+1] = min(dp[i]+1, dp[i*2+1]) ,如果 s[0…i]==s[i+1..i,则追加字符串*2+1]

    答案将存储在dp[n-1] 中,因为我们需要按索引形成字符串(0..n-1)。

    下面是上述想法的实现:

    C++
    // CPP program to print the
    // Minimal moves to form a string
    // by appending string and adding characters
    #include 
    using namespace std;
      
    // function to return the minimal number of moves
    int minimalSteps(string s, int n)
    {
      
        int dp[n];
      
        // initializing dp[i] to INT_MAX
        for (int i = 0; i < n; i++)
            dp[i] = INT_MAX;
      
        // initialize both strings to null
        string s1 = "", s2 = "";
          
        // base case
        dp[0] = 1;
      
        s1 += s[0];
      
        for (int i = 1; i < n; i++) {
            s1 += s[i];
      
            // check if it can be appended
            s2 = s.substr(i + 1, i + 1);
      
            // addition of character takes one step
            dp[i] = min(dp[i], dp[i - 1] + 1);
      
            // appending takes 1 step, and we directly
            // reach index i*2+1 after appending
            // so the number of steps is stord in i*2+1
            if (s1 == s2)
                dp[i * 2 + 1] = min(dp[i] + 1, dp[i * 2 + 1]);
        }
      
        return dp[n - 1];
    }
      
    // Driver Code
    int main()
    {
      
        string s = "aaaaaaaa";
        int n = s.length();
      
        // function call to return minimal number of moves
        cout << minimalSteps(s, n);
      
        return 0;
    }


    Java
    // Java program to print the
    // Minimal moves to form a string
    // by appending string and adding characters
    import java.util.*;
      
    class GFG
    {
      
    // function to return the minimal number of moves
    static int minimalSteps(String s, int n)
    {
      
        int []dp = new int[n];
          
        // initializing dp[i] to INT_MAX
        for (int i = 0; i < n; i++)
            dp[i] = Integer.MAX_VALUE;
      
        // initialize both strings to null
        String s1 = "", s2 = "";
          
        // base case
        dp[0] = 1;
      
        s1 += s.charAt(0);
      
        for (int i = 1; i < n; i++)
        {
            s1 += s.charAt(i);
      
            // check if it can be appended
            s2 = s.substring(i + 1, i + 1);
      
            // addition of character takes one step
            dp[i] = Math.min(dp[i], dp[i - 1] + 1);
      
            // appending takes 1 step, and we directly
            // reach index i*2+1 after appending
            // so the number of steps is stord in i*2+1
            if (s1 == s2)
                dp[i * 2 + 1] = Math.min(dp[i] + 1, 
                                       dp[i * 2 + 1]);
        }
        return dp[n - 1];
    }
      
    // Driver Code
    public static void main(String args[])
    {
      
        String s = "aaaaaaaa";
        int n = s.length();
      
        // function call to return minimal number of moves
        System.out.println(minimalSteps(s, n)/2);
    }
    }
      
    // This code is contributed by 
    // Shashank_Sharma


    Python3
    # Python program to print the 
    # Minimal moves to form a string 
    # by appending string and adding characters 
      
    INT_MAX = 100000000
      
    # function to return the 
    # minimal number of moves 
    def minimalSteps(s, n):
        dp = [INT_MAX for i in range(n)] 
          
        # initialize both strings to null 
        s1 = ""
        s2 = ""
          
        # base case 
        dp[0] = 1
        s1 += s[0]
          
        for i in range(1, n):
            s1 += s[i]
          
            # check if it can be appended 
            s2 = s[i + 1: i + 1 + i + 1]
          
            # addition of character 
            # takes one step 
            dp[i] = min(dp[i], dp[i - 1] + 1)
          
            # appending takes 1 step, and 
            # we directly reach index i*2+1 
            # after appending so the number
            # of steps is stord in i*2+1 
            if (s1 == s2): 
                dp[i * 2 + 1] = min(dp[i] + 1, 
                                    dp[i * 2 + 1])
          
        return dp[n - 1]
      
    # Driver Code 
    s = "aaaaaaaa"
    n =len(s)
      
    # function call to return 
    # minimal number of moves 
    print( minimalSteps(s, n) ) 
      
    # This code is contributed 
    # by sahilshelangia


    C#
    // C# program to print the
    // Minimal moves to form a string
    // by appending string and adding characters
    using System;
          
    class GFG
    {
      
    // function to return the minimal number of moves
    static int minimalSteps(String s, int n)
    {
      
        int []dp = new int[n];
          
        // initializing dp[i] to INT_MAX
        for (int i = 0; i < n; i++)
            dp[i] = int.MaxValue;
      
        // initialize both strings to null
        String s1 = "", s2 = "";
          
        // base case
        dp[0] = 1;
      
        s1 += s[0];
      
        for (int i = 1; i < n; i++)
        {
            s1 += s[i];
      
            // check if it can be appended
            s2 = s.Substring(i , 1);
      
            // addition of character takes one step
            dp[i] = Math.Min(dp[i], dp[i - 1] + 1);
      
            // appending takes 1 step, and we directly
            // reach index i*2+1 after appending
            // so the number of steps is stord in i*2+1
            if (s1 == s2)
                dp[i * 2 + 1] = Math.Min(dp[i] + 1, 
                                    dp[i * 2 + 1]);
        }
        return dp[n - 1];
    }
      
    // Driver Code
    public static void Main(String []args)
    {
      
        String s = "aaaaaaaa";
        int n = s.Length;
      
        // function call to return minimal number of moves
        Console.Write(minimalSteps(s, n)/2);
    }
    }
      
    // This code has been contributed by 29AjayKumar


    PHP


    输出:

    4
    

    时间复杂度: O(n 2 ),其中 n 是输入字符串的长度。

    如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程