题目描述
定义字符串的旋转操作为:
左旋转 L :把字符串前面的若干个字符移动到字符串的尾部,如把字符串abcdef左旋转2位得到字符串cdefab。
右旋转 R :把字符串后面的若干个字符移动到字符串的头部,如把字符串abcdef右旋转2位得到字符串efabcd
输入格式
第一行一个整数N(1<=N<=20)表示有N组测试数据。
接下来的N行,每行有一个字符串S(长度1<S<=15); 操作M; 旋转的位数n(0<=n<=20)。当操作M为L时,代表将字符串左旋转n 位,M为R时,代表将字符串右旋转n位,M为除了R和L的其它无效操作时,按要求输出。
方法一
#include <iostream>
using namespace std;
void changestring(string s, char a, int n)
{
int i = 0;
char temp = 0;
if (a == 'L')
{
for (int i = 0;i < n;i++)//移动n位
{
for (int i = 0;s[i + 1] != '\0';i++)//移动
{
temp = s[i];
s[i] = s[i + 1];
s[i + 1] = temp;
}
}
for (int i = 0;s[i] != '\0';i++)//输出
{
if(i%2==0) cout << s[i];
}
cout << endl;
}
else if (a == 'R')
{
for (int i = 0;i < n;i++)
{
for (int i = s.length();i > 1;i--)
{
temp = s[i - 1];
s[i - 1] = s[i - 2];
s[i - 2] = temp;
}
}
for (int i = 0;s[i] != '\0';i++)//输出
{
if (i % 2 == 0) cout << s[i];
}
cout << endl;
}
else
{
for (int i = 0;s[i] != '\0';i++)//输出
{
if (i % 2 == 0) cout << s[i];
}
cout << endl;
}
}
int main()
{
int N=0;
cin >> N;
string arr_string [20];//最多有二十个字符串
char arr_direction[20];//储存左移右移
int arr_int[20];//储存移动位数
for (int i = 0;i < N;i++)
{
cin >> arr_string[i]>> arr_direction[i]>> arr_int[i];
}
for (int i = 0;i < N;i++)
{
changestring(arr_string[i], arr_direction[i], arr_int[i]);
}
}
我一开始的思路是建立一个字符串数组,把每一个输入的字符串放进去。然后左旋转n位就是依次交换,这样的操作进行n次。
我在编写这个作业时发现的自己的问题:
①记不清数组的定义格式
数据类型+数组名+[]([]中间是数组的大小)
②要知道数组的长度必须得是固定的,因此不可以把输入的n作为数组的长度,所以我们要按照题目给的最多有20组测试数据,所以把数组长度设置为20。
③输入得和题给完全一致,cin>>…>>…这种形式代表空格输入。
④注意要写成第一个选择分支是if,下面的都是else if,最后是else。如果前面都是if最后else的话,就会造成if执行了也会进入else的情况(一个if和一个else对应)
⑤在右旋转时,我要从后往前交换,一直报错是因为当时一直用arr[i],i是从字符串长度开始递减的,所以事实上应该是arr[i-1],否则就会数组溢出了。
⑥发现自己对字符串的运用不够熟悉。
1.字符串判断空的条件是'\0',是右斜杠!!(我总是打成/)
2.字符串是一个特殊的char型数组,里面的每一位值储存在这个数组中,但是最后一位是‘\0'。正常的char型数组最后一位不是‘\0',但是如果你赋值的位数小于实际char型数组因此需要将循环条件写成s[i]!='\0',否则会造成数组访问越界。
3.因此一开始我想把字符串里面每个字符放到char型数组中是没有必要的,但是也有直接放到数组的方式。
方法一:
const char*k=NULL;
k=s1.c_str();
for(int i=0;k[i]!='\0';i++)
{
cout<<k[i]
}
思路就是定义一个k指针(是常量指针,就是指针的指向可以改变,但是指针指向内存的值不可以改变。复习:char const *k,指针指向不可以改变,但是指针指向内存的值可以改变)。
string这个类有很多封装的成员方法,c_str的意思就是返回当前字符串的首地址,但是是临时指针,因此必须得是const char *。这样k指针指向的就是字符串首地址,根据数组的本质是一个指针我们就知道k数组此时储存的就是字符串的数据了。
方法二
char s1[20];
strcpy(s1,s.c_str());
for(int i=0;s1[i]!='\0';i++) cout s1[i];
这个strcpy函数传入的参数不可以就是string,而是得是char型数组,所以我们用s.c_str获得这个数组!这样就把后面的char型数组的值复制给了前面的char型数组!
#include <iostream>
#include<string>
using namespace std;
void changestring(string s, char a, int n)
{
int i = 0;
char temp = 0;
if (a == 'L')
{
string s1;
string s1_m;
s1 = s.substr(0, n);//截取从字符串下标为0开始,长度为n的字符串
s1_m = s.substr(n, s.length() - n);//截取从字符串的第n+1位开始,长度为字符串长度-n的字符串
s1_m.insert(s1_m.length() , s1);//在原下标位s.length()的位置前插入s1
for (int i = 0;s1_m[i] != '\0';i++)//输出
{
if (i % 2 == 0) cout << s1_m[i];
}
cout << endl;
}
else if (a == 'R')
{
string s2;
string s2_m;
s2 = s.substr(s.length() - n, n);//截取从字符串下标为s.length()-n开始,长度为n的字符串
s2_m = s.substr(0, s.length() - n);//截取从字符串第一位开始,长度为字符串长度-n的字符串
s2_m.insert(0, s2);//在原下标位1的位置前插入
for (int i = 0;s2_m[i] != '\0';i++)//输出
{
if (i % 2 == 0) cout << s2_m[i];
}
cout << endl;
}
else
{
for (int i = 0;s[i] != '\0';i++)//输出
{
if (i % 2 == 0) cout << s[i];
}
cout << endl;
}
}
int main()
{
int N=0;
cin >> N;
string arr_string [20];//最多有二十个字符串
char arr_direction[20];//储存左移右移
int arr_int[20];//储存移动位数
for (int i = 0;i < N;i++)
{
cin >> arr_string[i]>> arr_direction[i]>> arr_int[i];
}
for (int i = 0;i < N;i++)
{
changestring(arr_string[i], arr_direction[i], arr_int[i]);
}
}
这个思路是受题目的启发:删除前n位,移到后面;删除后n位,移到前面。
再次习得一些string的函数:
s1=s.substr(i,n); 是截取字符串下标为i开始,长度为n的字符串返回。
s1.insert(i,s2);是指在字符串下标为i的位置前,插入s2字符串
当然,我们这题可以直接用+来拼接字符串。
但是不知道为什么,这种方法在oj系统上内存超了,不能过。(下节课问助教)
方法三
#include<iostream>
#include<string>
using namespace std;
int main()
{
char a[10001];
char b[10001];
int n, i_, m;
cin >> a;//输入到字符型数组中
cin >> m;//移动的位数
n = strlen(a);
for (int i = 0;i < n;i++)
{
i_ = (i + m) % n;
b[i_] = a[i];
}
b[n] = '\0';
cout << b;
return 0;
}
这是同学告诉我的方法,创建一个新的char型数组,然后按照对应序号放进去。
#include<iostream>
using namespace std;
struct my_char
{
char ch[15];
int n;
char direction;
};
void reverse(my_char a)
{
int num = strlen(a.ch);
char m_ch[15];
if (a.direction == 'L')
{
for (int i = 0;a.ch[i] != '\0';i++)
{
m_ch[(i + num - a.n) % num] = a.ch[i];
}
}
else if (a.direction == 'R')
{
for (int i = 0;a.ch[i] != '\0';i++)
{
m_ch[(i+a.n)%num] = a.ch[i];
}
}
int i = 0;
while (i < num)
{
if(i%2==0) cout << m_ch[i];
i++;
}
cout << endl;
}
int main()
{
int N;//储存几组数据
cin >> N;
my_char arr[20];//最多有20组数据
for (int i = 0;i < N;i++)
{
cin >> arr[i].ch >> arr[i].direction >> arr[i].n;
}
for (int i = 0;i < N;i++)
{
reverse(arr[i]);
}
}
自己运行成功了,但是不知道为什么OJ上编译失败,下节课问助教。