循环移动数组元素
来源:互联网 发布:cube world for mac 编辑:程序博客网 时间:2024/05/26 22:59
// 循环移动数组元素
// 一种大部分数据只移动一次的算法
// 方法:
// 将数据循环移动, 可以直接计算出每个数据的最终位置, 直接移动即可
// 分析:
// 这种算法基本可看做每个数据只需要移动一次
// 但是每个数据移动的位置需要计算, 算法理解起来比较难, 实现也比较复杂
// 另外,由于总是间隔较远存取数据,在数据数量较大的时候会导致比较频繁缓存命中失败
// 常用的两次翻转算法,每个数据需要swap两次(平均每个移动3次),而且很容易理解,实现也简单
#include "stdafx.h"
#include <algorithm>
#include <iostream>
// 最大公约数
size_t gcd(size_t n, size_t m)
{
if(n==0 || m == 0)
return 0;
while(true)
{
n %= m;
if(n == 0)
return m;
std::swap(n, m);
}
}
// 循环左移
template<typename T>
void CycleMove(T* data, size_t nLen, size_t nMov)
{
if(data == 0 || nLen <= 1)
return;
nMov %= nLen;
if(nMov == 0)
return;
// 分组处理
size_t nGroup = gcd(nLen, nMov);
// 每组数据数量
size_t nGroupSize = nLen / nGroup;
for(size_t i=0; i<nGroup; ++i)
{
// 保存第一个数
T d0 = data[i];
size_t iPosD = 0;
size_t iPosS = i;
// 先移动nGroupSize-1个
for(size_t j=1; j<nGroupSize; ++j)
{
// 数据位置
iPosD = iPosS;
iPosS += nMov;
iPosS %= nLen;
// 将数据左移
data[iPosD] = data[iPosS];
}
// 将第一个放到最后
data[iPosS] = d0;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char data[] = {-52, 83, 111, 103, 46, 115, 82, -111};
size_t nNum = sizeof(data)/sizeof(data[0]);
CycleMove(data, nNum, 3);
for(size_t i=0; i<nNum; ++i)
{
std::cout << (int)data[i];
if(i != nNum-1)
std::cout << " , ";
else
std::cout << std::endl;
}
return 0;
}
// 输出
// 103 , 46 , 115 , 82 , -111 , -52 , 83 , 111
- 循环移动数组元素
- 数组移动 数组元素循环右移问题
- 1008. 数组元素循环右移问题 (20)——数组循环移动算法
- 数组数据循环移动
- 数组循环移动
- 数组的循环移动
- 数组元素循环输出
- 移动数组中的元素
- 数组元素移动
- Java List 循环移动元素
- 完美算法 --将一个具有n个元素的数组向左循环移动i个位置
- 在一个升序的但是经过循环移动的数组中查找指定元素
- 数组中的数循环移动
- 循环删除数组中的元素
- 数组元素循环左移
- 数组元素的上下移动
- 组合有序数组 循环删除数组元素
- 将一个具有n个元素的数组向左循环移动i个位置,使用O(n)复杂度
- 在iphone工程属性设置时,使用相对路径
- JVM学习笔记之GC
- 单元文件结构
- 从无头单链表中删除节点--扩展:反转单链表
- JVM学习笔记之方法调用
- 循环移动数组元素
- ClassLoader介绍及ClassLoader.loadClass和Class.forName()的比较
- JQuery 遍历 XML
- ubuntu安装中文输入法
- 如何把电子表格Excel导入到sql 2005?
- 淘宝自主研发的海量数据库OceanBase开源
- 快速掌握 Objective-C (For C/C++ developer)
- wince6.0下应用程序自启动(总结)
- javascript开发中使用onpropertychange,oninput事件解决onchange事件的不足