📜  Java程序交换字符中的字符

📅  最后修改于: 2022-05-13 01:55:16.391000             🧑  作者: Mango

Java程序交换字符中的字符

给定一个长度为N的字符串S ,两个整数BC ,任务是从头开始遍历字符,将一个字符与 C 之后的字符交换,即交换位置i(i + C)%的字符ñ 。重复此过程B次,一次前进一个位置。你的任务是在B交换后找到最终的字符串。

例子:

Input : S = "ABCDEFGH", B = 4, C = 3;
Output:  DEFGBCAH
Explanation:
         after 1st swap: DBCAEFGH
         after 2nd swap: DECABFGH
         after 3rd swap: DEFABCGH
         after 4th swap: DEFGBCAH

Input : S = "ABCDE", B = 10, C = 6;
Output : ADEBC
Explanation:
         after 1st swap: BACDE
         after 2nd swap: BCADE
         after 3rd swap: BCDAE
         after 4th swap: BCDEA
         after 5th swap: ACDEB
         after 6th swap: CADEB
         after 7th swap: CDAEB
         after 8th swap: CDEAB
         after 9th swap: CDEBA
         after 10th swap: ADEBC

天真的方法

  • 对于较大的B值,循环B次的幼稚方法,每次将第 i 个字符与第(i + C)%N 个字符交换将导致高 CPU 时间。
  • 解决这个问题的诀窍是在每N次迭代后观察结果字符串,其中N是字符串S的长度。
  • 同样,如果C大于或等于N ,它实际上等于C除以N的余数。
  • 在此,让我们认为C小于N

有效的方法:

  • 如果我们观察每N次连续迭代和交换后形成的字符串(我们称之为一次完整迭代),我们就可以开始得到一个模式。
  • 我们可以发现字符串被分为两部分:长度为C的第一部分由S的前C个字符组成,第二部分由其余的字符组成。
  • 这两个部分旋转了一些地方。第一部分在每次完整迭代时向右旋转(N % C)个位置。
  • 第二部分在每次完整迭代时向左旋转C个位置。
  • 我们可以通过将B除以N来计算完全迭代的次数f
  • 因此,第一部分将向左旋转(N % C ) * f 。这个值可以超出C ,因此它实际上是( ( N % C ) * f ) % C ,即第一部分将旋转( ( N % C ) * f ) % C位置。
  • 第二部分将向左旋转C * f个位置。因为,这个值可以超出第二部分的长度,即(N – C) ,它实际上是( ( C * f ) % ( N – C ) ) ,即第二部分将旋转( ( C * f ) % ( N – C ) )名额。
  • f次完整迭代之后,可能还剩下一些迭代来完成B次迭代。该值为B % N ,它小于N 。我们可以在f次完整迭代后对这些剩余的迭代遵循朴素的方法来获得结果字符串。

下面是该方法的实现:

Java
// Java Program to find new after swapping
// characters at position i and i + c
// b times, each time advancing one
// position ahead
  
class GFG {
    // Method to find the required string
  
    String swapChars(String s, int c, int b)
    {
        // Get string length
        int n = s.length();
  
        // if c is larger or equal to the length of
        // the string is effectively the remainder of
        // c divided by the length of the string
        c = c % n;
  
        if (c == 0) {
            // No change will happen
            return s;
        }
  
        int f = b / n;
        int r = b % n;
  
        // Rotate first c characters by (n % c)
        // places f times
        String p1 = rotateLeft(s.substring(0, c),
                               ((n % c) * f) % c);
  
        // Rotate remaining character by
        // (n * f) places
        String p2 = rotateLeft(s.substring(c),
                               ((c * f) % (n - c)));
  
        // Concatenate the two parts and convert the
        // resultant string formed after f full
        // iterations to a character array
        // (for final swaps)
        char a[] = (p1 + p2).toCharArray();
  
        // Remaining swaps
        for (int i = 0; i < r; i++) {
  
            // Swap ith character with
            // (i + c)th character
            char temp = a[i];
            a[i] = a[(i + c) % n];
            a[(i + c) % n] = temp;
        }
  
        // Return final string
        return new String(a);
    }
  
    String rotateLeft(String s, int p)
    {
        // Rotating a string p times left is
        // effectively cutting the first p
        // characters and placing them at the end
        return s.substring(p) + s.substring(0, p);
    }
  
    // Driver code
    public static void main(String args[])
    {
        // Given values
        String s1 = "ABCDEFGHIJK";
        int b = 1000;
        int c = 3;
  
        // get final string
        String s2 = new GFG().swapChars(s1, c, b);
  
        // print final string
        System.out.println(s2);
    }
}


输出:
CADEFGHIJKB

时间复杂度:O(n)
空间复杂度:O(n)

有关更多详细信息,请参阅有关在字符串中交换字符的完整文章!