【算法编程】循环右移一个数组

仅用一个辅助节点将一个大小为n数组循环右移k位的三种办法:

1、时间复杂度最大:将所有元素每次只移动一位,总共移动k次,程序实现十分容易,在此就不具体实现了。

2、时间复杂度适中:依次将每个元素都放到辅助节点上,然后将其储存到目的节点,具体程序如下:

#include<iostream>
using namespace std;
int gcd(int x,int y);
int main()
{
        int n,k;
        cout<<"请输入数组的维数"<<endl;
        cin>>n;
        int *p=new int[n];
        for(int i=0;i<n;i++)
        {
                p[i]=i;
        }
        cout<<"请输入移动的位数"<<endl;
        cin>>k;
        k=k%n;
        int num=gcd(n,k);
        if(num==1)
        {
        int j=0;
        int temp=p[j];
        for(int i=0;i<n;i++)
        {
                j=(j+k)%n;
                temp=temp+p[j];
                p[j]=temp-p[j];
                temp=temp-p[j];
        }
        }
        else
        {
                for(int i=0;i<num;i++)
                {
                        int j=i;
                        int temp =p[i];
                        for(int ii=0;ii<n/num;ii++)
                        {
                                j=(j+k)%n;
                                temp=temp+p[j];
                                p[j]=temp-p[j];
                                temp=temp-p[j];
                        }
                }
        }
        for(i=0;i<n;i++)
        {
                cout<<p[i]<<" ";
        }
        cout<<endl;
        return 0;
}
int gcd(int x,int y)    //欧几里得辗转相除法求两数的最大的公约数
{
if(x<y)
        return gcd(y,x);
if(x%y!=0)
        return gcd(y,x%y);
else return y;
}

3、时间复杂度最小,总共只移动n+1次,具体思路如下:首先将一个元素放入辅助节点,由于要移动k位,肯定有一个元素会移动到刚才的节点,以此类推,最后肯定会空余一个节点,然后将辅助节点的元素放入即可。具体程序实现如下:

#include<iostream>
using namespace std;
int gcd(int x,int y);
int main()
{
        int n,k;
        cout<<"请输入数组的维数"<<endl;
        cin>>n;
        int *p=new int[n];
        for(int i=0;i<n;i++)
        {
                p[i]=i;
        }
        cout<<"请输入移动的位数"<<endl;
        cin>>k;
        k=k%n;
        int num=gcd(n,k);
        if(num==1)
        {
                int j=0;
                int temp=p[0];
                for(int i=0;i<n-1;i++)
                {
                        p[j]=p[(j+n-k)%n];
                        j=(j+n-k)%n;
                }
                p[(n-1)*(n-k)%n]=temp;
        }
        else
        {
                for(int i=0;i<num;i++)
                {
                        int j=i;
                        int temp =p[j];
                        for(int ii=0;ii<n/num-1;ii++)
                        {
                                p[j]=p[(j-k+n)%n];
                                j=(j-k+n)%n;
                        }
                        p[((n/num-1)*(n-k)+i)%n]=temp;
                }
        }
        for(i=0;i<n;i++)
        {
                cout<<p[i]<<" ";
        }
        cout<<endl;
        return 0;
}
int gcd(int x,int y)
        //欧几里得辗转相除法求两数的最大的公约数
{
        if(x<y)
                return gcd(y,x);
        if(x%y!=0)
                return gcd(y,x%y);
        else return y;
}

原文:http://blog.csdn.net/tengweitw/article/details/24925075

作者:nineheadedbird

时间: 2024-10-03 17:32:56

【算法编程】循环右移一个数组的相关文章

【算法思想】循环移动一个数组

问题:如何将一个数组循环左移或者右移k位?     在下面的解决方案中,我们以循环左移为例. 我们最容易想到的是,将前k个元素复制到一个临时的数组中,然后将剩下的n-k个元素向左移动k个位置,然后将之前的k个元素复制到剩下的位置.这种方法使用了k个额外的存储空间.我们想到到另一种方法是,只借助一个临时空间,每次只向左移动1位,循环k次.这种方法产生了多于的运行时间.前面一篇文章中用程序实现了循环右移一个数组的算法.前面提到的都是比较常规的算法,下面从其它角度来考虑这一问题:     循环数组x其

代码-用递归能实现一个数组划分的算法么?

问题描述 用递归能实现一个数组划分的算法么? 用递归能实现一个数组划分的算法么? 给一个数组,长度为m,划分成n个子数组(每个数组起码有一个元素),比如 {1 2 3 4 5}划分成2个: 1, 2345 12,345 123,45 1234,5一共5个分法 {1234}分成3个 1,2,34 1,23,4 12,3,4,一共3个分法 求代码怎么写 解决方案 IEnumerable<IEnumerable<IEnumerable<int>>> Split(IEnumer

java-有一个数组,数组里任意个数数字相加等于一固定数值,求出所有可能性的任意数字组合?

问题描述 有一个数组,数组里任意个数数字相加等于一固定数值,求出所有可能性的任意数字组合? 最近遇到一道java算法题,给定一个数组,求出数组里任意个数相加等于一固定数值,求出所有可能性的任意数字组合?求解答,用最原始的算法做出这道题,求大神指点,大神给出答案? 解决方案 /** * * @param arr * 数组 * @param num * 固定值 * @return 组合 */ public static List a(int[] arr, int num) { List strLis

c语言-请教一个C编程 打印输出图像的算法编程

问题描述 请教一个C编程 打印输出图像的算法编程 解决方案 大概就是这样,建立笛卡尔坐标系. 用point()函数里的嵌套for循环来输出每一个字符,然后把代表坐标的i和j传递给getChar()函数通过坐标来决定输出的是什么字符. 解决方案二: char getChar(int x,int y,int n) { if(x<0) x=-x; if(y<0) y=-y; if(x>y) { if(n-x<=2) return 'x'+n-x; else return '0'+n-x-

[算法问题]合并两个已经排序的数组为另一个数组

问题描述: 设子数组a[0:k]和a[k+1:n-1]已排好序(0<=k<=n-1).试设计一个合并这两个子数组为排好序的数组a[0:n-1]的算法.要求算法在最坏的情况下所用的计算时间为O(n), 且只用到O(1)的辅助空间. 这一题比较简单,看代码就知道了. #include <stdio.h> void DisplayArray(int *pArray, int nLen) { for (int i = 0; i < nLen; ++i) { printf("

c++-为什么这段代码循环输出的数组少了第一个元素且多出了一个随机数?

问题描述 为什么这段代码循环输出的数组少了第一个元素且多出了一个随机数? 输入一些非负实数 用数组输出这些数 求平均数并输出(输入负数时报错并退出重新输入,输入回车时执行下一步操作) #include using namespace std; int main() { int i,j,k; double a[100],sum=0,avr; part1: cout<<"输入数字"< j=0,k=0; for (i=0;getchar()!='n';i++) { cin&

文件系统-VB如何用二进制打开一个jpg 文件存到一个数组,每次存256循环存完。

问题描述 VB如何用二进制打开一个jpg 文件存到一个数组,每次存256循环存完. 硬盘已经有文件,Dim fileName As String '定义了文件路径Dim plainText() As Byte'用来存放照片二进制数据文件的数组 Open fileName For Binary As 1#'我已经写了用二进制打开文件 '现在循环就不知道怎么写了,想每次存256个字节到plainText()数组一直循环到整个照片全部存入数组.For i=1 To FileLen(fileName)'

用一个数组、头指针和元素个数合在一起所构成的结构来存储顺序队列,设计算法以实现队列的各运算。

问题描述 用一个数组.头指针和元素个数合在一起所构成的结构来存储顺序队列,设计算法以实现队列的各运算. 用一个数组.头指针和元素个数合在一起所构成的结构来存储顺序队列,设计算法以实现队列的各运算. 解决方案 http://www.docin.com/p-524422606.html

推荐一个算法编程学习中文社区-51NOD【算法分级,支持多语言,可在线编译】

    最近偶尔发现一个算法编程学习的论坛,刚开始有点好奇,也只是注册了一下.最近有时间好好研究了一下,的确非常赞,所以推荐给大家.功能和介绍看下面介绍吧.首页的标题很给劲,很纯粹的Coding社区....虽然目前人气可能一般,但这里面题目和资源还是比较丰富的,希望给初学者一个帮助. 本文原文地址:[推荐]一个算法编程学习中文社区-51NOD[算法分级,支持多语言,可在线编译] 1.51NOD论坛介绍     该论坛网址:http://www.51nod.com/index.html     论