数组循环移位

来源:互联网 发布:软件设计师大纲 编辑:程序博客网 时间:2024/06/04 01:04

题目摘要

给定一个数组,要求将数组向右循环移位K次,求所得的新的数组。

题目分析

给如下实例,如abcd1234循环移位4次,abcd1234→4abcd123→34abcd12→234abcd1→1234abcd

一种很简单的求解方法就是每次移一位,循环移动K次,代码如下:

#include"stdio.h"#include"stdlib.h"#include"string.h"#define N 100int main(){    int i, k, temp;    char s[N];    scanf_s("%s", s, N);    scanf_s("%d", &k);    i = strlen(s);    //处理k>i情况    k = k%i;    while (k)    {        i = strlen(s);        temp = s[i - 1];        for (i = strlen(s); i > 0; i--)        {            s[i - 1] = s[i - 2];        }        s[0] = temp;        k--;    }    printf("%s\n", s);    system("pause");    return 0;}

通常情况下,我们默认k是小于n的,但是实际上,k>n也未尝不可,反正一个字符循环移位n次后就会得到它本身,所以我们只需要考虑k%n就可以了,这个算法的复杂度为O(N*N)。
值得一提的是,VS新版本中输入字符串用scanf_s(“%s”,s)编译无法通过,必须在后面再加一个缓冲区大小才行scanf_s(“%s”, s, N)。

第二种方法,是调用string.h里面的函数strncpy(s2,s1+i,k)该函数是将字符串s[i]到s[i+k]这一段截取出来存到s2中。
然后再将s1中剩余部分连到s2后面即可。
代码如下:
PS:reverse函数在这里并没有用到,该函数主要实现的是数组原地逆序,第三种方法用到的reverse函数跟这里的差不多,区别仅仅是数组某一部分的逆序。

#include"stdio.h"#include"stdlib.h"#include"string.h"#define N 100//这种解法默认的是k<n的,但是实际情况下k>n也很常见char* reverse(char s[]){    char ch;    int length = strlen(s);    for (int i = 0; i < (length / 2); i++)    {        ch = s[i];        s[i] = s[length - 1 - i];        s[length - 1- i] = ch;    }    return s;}int main(){    char str1[N], str2[N];    int k,len;    scanf_s("%s", str1, N);    scanf_s("%d", &k);    len = strlen(str1);    //循环右移n位(n为字符串的长度)后会回到原来位置    k = k%len;    str1[len] = '\0';    strncpy_s(str2,str1+len-k,k);    str1[len - k] = '\0';    //reverse(str2);    strcat_s(str2, str1);    printf("%s\n", str2);    system("pause");    return 0;}

在《编程之美》中,作者提出了一种复杂度为O(n)的算法。注意到循环移位中,a[0,length-k-1]和a[length-k,length-1]这两段的顺序是不会变的,右移k位实质上就是交换这两个部分。
例如abcd1234循环4次
I.逆序abcd:abcd1234→dcba1234
II.逆序1234:dcba1234→dcba4321
III.全部逆序:dcba4321→1234abcd
代码如下:

#include"stdio.h"#include"stdlib.h"#include"string.h"#define N 100char* reverse(char s[],int m,int n){    int length = n - m + 1;    char temp;    //原地逆序    for (int i = 0; i < (length / 2); i++)    {        temp = s[i+m];        s[i+m] = s[length-1-i+m];         s[length-1-i+m] = temp;    }    return s;}int main(){    char s[N];    int i, k, len;    scanf_s("%s", s, N);    scanf_s("%d", &k);    len = strlen(s);    k %= len;    reverse(s,0,len-k-1);    reverse(s, len - k, len - 1);    reverse(s, 0, len - 1);    printf("%s\n", s);    system("pause");    return 0;}
原创粉丝点击