我的算法记录——04数组循环左移

题目

浙大版《数据结构(第2版)》题目集——习题2.2 数组循环左移


本题要求实现一个对数组进行循环左移的简单函数:一个数组a中存有n(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向左移m(≥0)个位置,即将a中的数据由(a0​a1​⋯an−1​)变换为(am​⋯an−1​a0​a1​⋯am−1​)(最前面的m个数循环移至最后面的m个位置)。如果还需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?

输入格式:

输入第1行给出正整数n(≤100)和整数m(≥0);第2行给出n个整数,其间以空格分隔。

输出格式:

在一行中输出循环左移m位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。

输入样例:

8 3
1 2 3 4 5 6 7 8

 输出样例:

4 5 6 7 8 1 2 3

一、解题思路

        想要循环左移,本质上就是前m个数(当m大于n时取余,确保合理的移动数字)按顺序“后输出”,而其他数字按顺序“先输出”即可,而需要“后输出”的数字,肯定是需要临时变量存储的,故定义一个数组s[],并且大小最大就是n(当m是n的倍数时输入的n个数字都需要存入临时数组“后输入”)。而如何找出“后输出”的序列,和“先输出”的序列呢?其实只需要在输入阶段用if-else判断即可:在for循环输入中,当i<m时(m需要对n取余,达到类似“循环”的效果,具体细节运行一下代码,换几个数据感受一下吧^_^)就把这些数字存入数组s中,其余的就是需要先移动的,直接用一个临时变量t去存储按顺序输入进来的数,然后printf输出即可。最后就是按顺序输出临时数组s中的数字(还有一个问题是要满足题目中的“序列结尾不能有多余空格”问题,我放在代码中解释了)

二、代码

#include<stdio.h>
int main(){
    int n,m,i,t;
    scanf("%d%d",&n,&m);
    int s[n];
    for(i=0;i<n;i++){
        //i小于需要移动的次数,说明此次输入的数字需要循环向左移动,
        //循环向左的本质就是,让这m%n个数字(由于m可能大于和为n的倍数,所以需要取余来限制)
        //“待会儿输出”,那我们不妨不循环挨个移动再输出,而是先存着这几个数,
        //等需要“先输出”的数字输出完了,再通过一个循环输出在后面即可
        if(i<m%n)
        scanf("%d",&s[i]);
        else{
            //else则说明需要“先输出”的数字,先简单用一个临时变量t储存,
            // 但是未来满足“序列结尾不能有多余空格”,需要再判断一下是否是最后一个需要“先输出”的元素
        scanf("%d",&t);
            if(i+1!=n)//如果不是最后一个需要“先输出”的元素
            printf("%d ",t);
            else//最后一个“先输出”的元素
            printf("%d",t);
        }
        
    }
    for(i=0;i<m%n;i++){
        //由于“先输出”的序列结尾元素是“空格”+“数字”的形式
        //例如题目所给样例中,“先输出”的数字序列是:4 5 6 7 8
        //所以为了满足“序列结尾不能有多余空格”,直接按:“空格”+数字即可
        printf(" %d",s[i]);
    }
    return 0;
}

 结果如图:


总结

        一开始是想着简单的用类似于冒泡排序的方式去做,然后结合昨天晚上看了浙大版《数据结构》书中第一章解决有关“最大子列和”问题(也是题集的上一道题)的“[算法1.4] 在线处理”思想,尝试想想也有没有这种“在线”的方式做这道题呢,然后突发奇想(当然,没看其他题解自己做的,有许多问题还望不吝赐教^_^)想到了这题“先输出”和“后输出”的两种情况对数组循环左移的题解。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值