打印

请教算法高手,数组数据如何快速移位操作

[复制链接]
6094|23
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
古道热肠|  楼主 | 2008-2-1 12:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
概述:应用中需要将数组的数据整体进行一次左移或右移操作,如何简单,快捷,通用地实现。
详述:
  比如:Temp[4] = {0x80,0x40,0x20,0x10};
左移一次变成Temp[4] = {0x00,0x80,0x40,0x20)};
再移一次变成Temp[4] = {0x01,0x00,0x80,0x40};
备注:
1、数组的长度可能是8甚至更多,例子用4个数据是为了说明简单
2、为了提高通用性和可移植性,尽量不要采用嵌入式汇编来实现,宜用ANSI C来实现。
3、目前已测试过实现过的方法是先左移Temp[0],再拆分Temp[1]的最高位内容,装配到Temp[0]的最低位,循环到数组的所有单元都完成,此法占用CPU时间太多。

相关帖子

沙发
john_light| | 2008-2-1 12:18 | 只看该作者

用硬件实现

呵呵

使用特权

评论回复
板凳
HWM| | 2008-2-1 12:21 | 只看该作者

要通用看来只有LZ自己所说的办法,别无它法。

使用特权

评论回复
地板
gyt| | 2008-2-1 12:30 | 只看该作者

改变上层算法

如果执行时间确实很重要的话

使用特权

评论回复
5
mohanwei| | 2008-2-1 13:40 | 只看该作者

很简单,用环形队列算法。只需用头指针和尾指针描述一下

移位时,就是一个指针++/--的操作

使用特权

评论回复
6
LastNew| | 2008-2-1 14:14 | 只看该作者

ls搞笑了吧

俺来出个馊主意:

     例子中:从Temp【4】开始逐个元素进行处理,可以写成函数,逐个乘2,记住它的进位(0、1)并作为下一次移位时调用函数的参数给加上(初始为o,这样一个数组要对应一个变量)。
     这样来基本可以通用,简单;快捷就不一定了。这样是最直接的作法。如果数组的数有规律的话,也许可以通过查表的方法来空间换时间

使用特权

评论回复
7
LastNew| | 2008-2-1 14:16 | 只看该作者

晕了

俺晕了,发现跟古板的方法差不多,哈哈

本来嘛,古板何等人物,丢人俺也不怕了,嘿嘿

使用特权

评论回复
8
LastNew| | 2008-2-1 14:27 | 只看该作者

不知道这样可以不

跟我上面说的差不多流程,只不过函数换成intrins.h里面左移或循环左移指令的组合。要通用可以这样:先把参数写入CY,对N个元素执行循环左移,再把CY读出来给变量。如果这个方法可以的话基本是通用,简单,快捷了。因为它就是汇编写法的翻版,对不?
        

使用特权

评论回复
9
LastNew| | 2008-2-1 14:28 | 只看该作者

菜鸟见笑了:(

  

使用特权

评论回复
10
雁舞白沙| | 2008-2-1 14:43 | 只看该作者

是这个意思吗?

for(i=0;i<4;i++)
        {
            j=DataBuf & 0xf0;
            j=j>>4;
            LedShowBuf[i+i]=Digit[j];
            j=DataBuf[i+1] & 0x0f;
            LedShowBuf[i+i+1]=Digit[j];
        }

使用特权

评论回复
11
mohanwei| | 2008-2-1 16:53 | 只看该作者

晕,看了半天小说,一目十行,眼花了……

想通用就只有楼主自己的方法3了;
如果是特定的平台,自然可以利用一些特殊指令来优化,例如51的“RL/RLC”……

使用特权

评论回复
12
machunshui| | 2008-2-1 17:19 | 只看该作者

考虑用4个字节的数据类型执行一次移位操作

unsigned char * tempx,强制类型成unsigned int * tempy,对*tempy执行移位,装配发生在4个字节的边界.

最后不够4个字节的专门处理一下.

使用特权

评论回复
13
machunshui| | 2008-2-1 17:30 | 只看该作者

装配的另一种方法

对上一次的移位的4字节的最低一个字节,执行一次右移,再与后面的三个字节组成四字节的数据类型,执行左移.

使用特权

评论回复
14
deeploves| | 2008-2-1 19:59 | 只看该作者

应该很简单啊

用类型转换把4个字节的char组合成1个int位,然后向左移1位,再把int类型转换成4个char位

如果支持64位或128位也是一样的道理,也就C语言的三行就完成了

使用特权

评论回复
15
machunshui| | 2008-2-1 20:56 | 只看该作者

三行怎么能完成?

128三行怎么能完成?

两个int型的边界要不要处理?

使用特权

评论回复
16
deeploves| | 2008-2-1 21:33 | 只看该作者

如下

如果是32位
char t[4];
int  * t;

 r = t;
 r = r << 1;
 
如果是64位
char t[8];
long * t;

 r = t;
 r = r << 1;

如果是128位
char t[16];
long long * t;

 r = t;
 r = r << 1;

我以前用过,不过不同的编译器可能要测试一下是大端还是小端模式,还有我是在32位机上玩的,不是8位机

使用特权

评论回复
17
machunshui| | 2008-2-1 22:16 | 只看该作者

很多编译器的long行是4个字节的

很多编译器的long型号是4个字节的.long long也只是8个字节.

long long型确实不错,没用过,倒是没有想到.

int型一般都是4个字节,比较通用.

但是不管是多少,对两个最大数据类型的边界,总是要处理的.

使用特权

评论回复
18
deeploves| | 2008-2-1 22:28 | 只看该作者

对两个最大数据类型的边界,总是要处理的

我不明白最大数据类型的边界这里是指什么意思?

使用特权

评论回复
19
machunshui| | 2008-2-1 22:39 | 只看该作者

楼主未限定数组的长度

楼主未限定数组的长度.
4个字节只是楼主举例子.

本次int型的最高位要移动到上次的int型的最低未.

使用特权

评论回复
20
xhtxzxw| | 2008-2-1 23:46 | 只看该作者

嘿嘿

LZ是高高手,在考大家吧?
我很笨,写个笨办法(以左移为例),因为担心算符的优先级,括号用得比较多,呵呵
void Lshift_bit_in_bytes(char x[], char len)
{
    char i;
    for(i=0; i<len-1; i++)
        x = (char)(((int)(x<<8 + x[i+1]))>>8);
    x[len-1] <<= 1;
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

284

主题

6411

帖子

16

粉丝