内存移动算法

原创 2006年06月16日 20:43:00

原文参见《程序员》杂志2006年第6期。现对原文做部分摘录,并给出自己的算法。

    问题: 对于有K个元素的数组int a[k]={.......};写一个高效算法将数组内容循环左移m位,
比如:int a[6]={1,2,3,4,5,6},循环左移3位后得到结果{4,5,6,1,2,3}.
    要求:1.不允许另外申请数组空间,但可以申请少许变量;
         2.不允许采用每次左移。
    最直观的想法,就是从第一个元素开始,把他一步移动到最终目的位置,而该位置原有的元素的值取出,移动到它的新位置。递归进行这个步骤。
    首先,我们在数学上很容易理解,这是一个一一对应映射,绝不会在一个位置上出现两次移动。所以不会出现移动的递归过程中途指向了已经移动过的元素。
    那么,这个递归过程唯一的终止条件就是,当前移动的元素,目的位置就是移动过程的起始位置。
    如果按照元素的索引下标标示元素,0到k-1中的任意元素i,会移动到什么位置?
    对于任意的i,它的新位置i'=((k-m) + i)%k.
    那么,我们可以定义这个循环链,取整数i0,使得0=<i0<m,定义i1=((k-m) + i0)%k,i2=((k-m) + i1)%k....ix=((k-m) + ix-1)%k.当ix=i0时循环终止。此时有i0=ix=((k-m) + ix-1)%k=....
=(x(k-m) + i0)%k
    因为我们知道0<i0<m,所以有0=x(k-m)%k,也就是说,x(k-m)=yk,因为我们是遇到第一个x(k-m)=yk就终止,显然等号左右的值就是k-m和k的最小公倍数。根据数论知识,我们知道,k,m,k-m这三个数有最大公约数q,使得k=aq,m=bq,k-m=cq,a,b,c三个数两两互质,进而推出x=a,y=c。也就是说,这个递归过程会经历a步。
    因为我们知道整个过程一共a步,k=aq,那么i到ix的序列会形成一个步长为q的等差序列,所以我们要移动整个0到k-1的区间,应该对0到q-1的元素应用这个递归算法。
    该算法的时间复杂度为O(n),空间复杂度为O(1).

   int CommonFactor(int dividend,int divisor)//求最大公约数函数
 {
     if(dividend<divisor)
        {
           int temp=dividend;
           dividend=divisor;
           divisor=temp;
 }
     int remainder=dividend%divisor;
     while(remainder!=0)
      {
        dividend=divisor;
        divisor=remainder;
        remainder=dividend%divisor;
      }
    return divisor;
  }

void shift1(int a[],int k,int m)//k是数组a的元素个数,m是循环左移m位
 {
    int i,j,n,q=CommonFactor(k,k-m);
    for(n=0;n<q;n++)
    {
       int temp=x[n]; i=n;j=(i+m)%k;
       while(j!=n)
         {
           x[i]=x[j];
           i=j;
           j=(i+m)%k;
  } 
     x[i]=temp;
   }
 }


同理可以分析循环右移m位的算法
void shift1(int a[],int k,int m)//k是数组a的元素个数,m是循环右移m位
 {
    int i,j,n,q=CommonFactor(k,m);
    for(n=0;n<q;n++)
    {
       int temp=x[n]; i=n;j=(k+i-m)%k;
       while(j!=n)
         {
           x[i]=x[j];
           i=j;
           j=(k+i-m)%k;
  } 
     x[i]=temp;
   }
 }

字符串同构判定

 public class Same { public boolean checkSam(String stringA, String stringB) { int len...

编程练习4--字符串同构

给定两个字符串,请编写程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。这里规定大小写为不同字符,且考虑字符串重点空格。 给定一个string stringA和一个string s...

内存移动算法

内存移动算法个人笔记,转载请联系本人本篇笔记也被放在我的github上,那里有详细的代码。概述算法课上老师介绍了内存移动算法。说实话,当时并没有听懂。原因是对这个没什么感触,体会不到关键点在哪里。问题...

移动学习 AndroidStudio内存优化分析—hprof文件分析

1、移动学习在主界面时按如下顺序点击: 2、其实和 android内存分析 outOfMemoryError错误定位及分析策略(非显示图片造成) 中用eclipse前7步的设置一样,只不过这个速度...
  • jbb0403
  • jbb0403
  • 2017年07月06日 17:38
  • 846

Android移动开发 ListView使用BaseAdapter与ListView的优化,内存优化处理(转载)

Android ListView使用BaseAdapter与ListView的优化 您的评价:        收藏该经验 在...

UWA 发布| MMO移动游戏性能分析报告:渲染、UI、逻辑代码和内存需重点关注

原文链接:http://blog.uwa4d.com/archives/PerformanceReport_MMO.html 两个月前,UWA发布了Unity性能数据分析报告,对提交测试(登陆w...
  • UWA4D
  • UWA4D
  • 2017年01月11日 15:50
  • 460

Unity3D移动平台内存优化

 最近网友通过网站搜索Unity3D在手机及其他平台下占用内存太大. 这里写下关于Unity3D对于内存的管理与优化. Unity3D 里有两种动态加载机制:一个是Resources.Lo...

写一个函数,完成内存移动,并为其写一个简单的测试用例来进行测试

本文是我们训练程序员的系列文章之一,仅供参考!  这几年在全国巡回招聘应届毕业生的过程中,经常会遇到这样的现象:有些同学对自己的笔试比较满意,可是最后却得不到面试的机会,心里大为不解,颇...

在内存中的显示缓存区中显示移动的汉字”中“字

源代码: assume cs:code,ds:data data segment DB 080H, 001H, 080H, 001H, 080H, 001H, 0FCH, 03FH, ...
  • mxzzyq
  • mxzzyq
  • 2012年12月20日 19:44
  • 220
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:内存移动算法
举报原因:
原因补充:

(最多只允许输入30个字)