右旋字符串|笨方法和巧思

 题目:

题目描述

字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。 

例如,对于输入字符串 "abcdefg" 和整数 2,函数应该将其转换为 "fgabcde"。

输入描述

输入共包含两行,第一行为一个正整数 k,代表右旋转的位数。第二行为字符串 s,代表需要旋转的字符串。

输出描述

输出共一行,为进行了右旋转操作后的字符串。

输入示例

2

abcdefg

输出示例

fgabcde

提示信息

数据范围:
1 <= k < 10000,
1 <= s.length < 10000;

 


思路:

看到字符串反转,移动一类

首先会想到指针或者reverse方法

两种都比较好实现

只要思路对,代码秒AC


解题过程

1.指针

本来想使用双指针从后更新元素,再将所需移动的元素填入前端空出来的位置

编写实现过程中发现

        1.必须要定义一个新的容器来存储待移动元素,不然从后覆盖会导致这部分丢失

        2.记录和后移过程不能同时进行,他们的长度是不一样的

  那么解决这些问题就需要先定义一个数组之类的,虽然已知这个容器的大小为k

但k是变量,不能直接定义一个大小为k的字符数组用于保存待移动元素

只能使用vector动态申请内存

然后使用三个for循环,分别用于记录待移动的元素、移动元素,实现右旋

是很笨很笨很浪费空间时间的方法了。。。。

具体代码如下

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
    int k;
    cin>>k;
    string s;
    cin>>s;
    int len=s.size();
    不太高明之想用双指针但发现不适用版
     //需要一个可以存放被移动元素的数组?字符串?
     //并且大小已知为k,但k是变量不能直接用数组定义
     //动态申请内存
     vector<char> t(k);
     // 记录被移动的元素,从 t 的第 k-1 位开始倒序存储
     for(int j = len - 1, i = k - 1; j >= len - k; j--, i--){
         t[i] = s[j];
     }
     for(int j=len-1;j>=k;j--){
         //移动元素
         s[j]=s[j-k];
     }
     //记录被移动元素和移动元素不能同时进行
     //他们所操作的元素个数并不相同
     for(int i=0;i<k;i++){
        s[i]=t[i];
    }
    cout<<s<<endl;
    retrun 0;
}

2.reverse方法 

可以先思考右旋和反转间的关系

本题相当于对两串字符串实现对调

但没有对应库函数可以实现

那么这里用个巧思

先局部局部反转

再整体反转就可以得到正确结果

用样例说明

初始输入:abcdefg

反转前一段:edcbafg

反转后一段:edcbagf

全部反转:fgabcde

当然先整体再前一段再后一段也是一样的

只需要确保反转位置无误即可

具体代码如下

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
    int k;
    cin>>k;
    string s;
    cin>>s;
    int len=s.size();
    //使用反转
    //可以说是聪明人才想的到的巧妙转法
    // 先反转前一段,长度len-n ,
    reverse(s.begin(), s.begin() + len - k); 
    // 再反转后一段
    reverse(s.begin() + len - k, s.end()); 
    // 整体反转
    reverse(s.begin(), s.end()); 

    cout<<s<<endl;
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值