C++程序 交换字符串中的字符

C++程序 交换字符串中的字符

给定长度为 N 的字符串 S ,以及两个整数 BC ,任务是从开头开始遍历字符,将一个字符与它后面第C个地方的字符交换位置,即交换位置为 i(i + C)%N 的字符。重复进行这个过程 B 次,每次向前移动一个位置。您的任务是找到进行 B 次交换后的最终字符串。

例子:

输入: S = “ABCDEFGH”, B = 4, C = 3;
输出: DEFGBCAH
解释:
经过第一次交换:DBCAEFGH
经过第二次交换:DECABFGH
经过第三次交换:DEFABCGH
经过第四次交换:DEFGBCAH

输入: S = “ABCDE”, B = 10, C = 6;
输出: ADEBC
解释:
经过第一次交换:BACDE
经过第二次交换:BCADE
经过第三次交换:BCDAE
经过第四次交换:BCDEA
经过第五次交换:ACDEB
经过第六次交换:CADEB
经过第七次交换:CDAEB
经过第八次交换:CDEAB
经过第九次交换:CDEBA
经过第十次交换:ADEBC

Naive Approach:

  • 对于较大的 B 值,每次循环 B 次,每次将第 i 个字符与 (i + C)%N 个字符交换,将导致高CPU时间。
  • 解决此问题的技巧是观察每次迭代后的结果,每次迭代 N 次,其中 N 是字符串 S 的长度。
  • 再次,如果 C 大于或等于 N ,则它等效于 C 除以 N 的余数。
  • 此后,让我们将 C 视为小于 N

下面是该方法的实施:

// C++ Program to Swap characters in a String
#include <iostream>
#include <string>
 
using namespace std;
 
string swapCharacters(string s, int B, int C)
{
    int N = s.size();
    // If c is greater than n
    C = C % N;
    // loop to swap ith element with (i + C) % n th element
    for (int i = 0; i < B; i++) {
               swap(s[i % N], s[(i + C) % N]);
    }
    return s;
}
 
int main()
{
    string s = "ABCDEFGH";
    int B = 4;
    int C = 3;
    s = swapCharacters(s, B, C);
    cout << s << endl;
    return 0;
}
 
// This code is contributed by Susobhan Akhuli```  

输出

DEFGBCAH

时间复杂度: O(B),迭代B次。

空间复杂度: O(1)

高效做法:

  • 如果我们观察每次连续交换后形成的字符串(假定称之为一个完整迭代),我们可以开始找到一种模式。
  • 我们可以发现该字符串被分成两部分:长度为 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 。在完整迭代后,我们可以按照朴素的方法处理这些剩余迭代,以获得结果字符串。

示例:

s = ABCDEFGHIJK; c = 4;

部分:ABCD EFGHIJK

一次完整迭代后:DABC IJKEFGH

两次完整迭代后:CDAB FGHIJKE

三次完整迭代后:BCDA JKEFGHI

四次完整迭代后:ABCD GHIJKEF

五次完整迭代后:DABC KEFGHIJ

六次完整迭代后:CDAB HIJKEFG

七次完整迭代后:BCDA EFGHIJK

八次完整迭代后:ABCD IJKEFGH

下面是该方法的实现:

// C++程序找到交换位置i和i+c后新的字符串
// b次,每次前进一位
#include <bits/stdc++.h>
using namespace std;
 
string rotateLeft(string s, int p)
{
     
    //将一个字符串向左转动p次,实际上是将前p个
    //字符剪切到字符串的末尾
    return s.substr(p) + s.substr(0, p);
}
 
//方法找到需要的字符串
string swapChars(string s, int c, int b)
{
     
    //获取字符串长度
    int n = s.size();
     
    //如果c大于或等于字符串长度,则实际上是
    //c除以字符串长度的余数
    c = c % n;
     
    if (c == 0)
    {
         
        //不会发生任何改变
        return s;
    }
    int f = b / n;
    int r = b % n;
     
    //将前c个字符旋转(n % c)*f%c**位**
    //位置f次
    string p1 = rotateLeft(s.substr(0, c),
                  ((n % c) * f) % c);
                   
    //将剩余的字符旋转n*f个位置
    string p2 = rotateLeft(s.substr(c),((c * f) % (n - c)));
                   
    //连接两个部分并将
    //完整迭代后形成的结果字符串转换为字符串数组
    //(用于最后的交换)
    string a = p1 + p2;
     
    //剩余交换
    for(int i = 0; i < r; i++)
    {
         
        //将第i个字符与
        //(i + c)th字符交换
        char temp = a[i];
        a[i] = a[(i + c) % n];
        a[(i + c) % n] = temp;
    }
     
    //返回最终字符串
    return a;
}
 
//驱动程序
int main()
{
     
    //给定值
    string s1 = "ABCDEFGHIJK";
    int b = 1000;
    int c = 3;
     
    //获取最终字符串并打印最终字符串
    cout << swapChars(s1, c, b) << endl;
}
 
//此代码由rag2127提供```  

输出:

CADEFGHIJKB

时间复杂度 :O(n)

空间复杂度 :O(n)

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

C++ 示例