Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/101.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 快速高效的数组查找和修改_Arrays_Lookup - Fatal编程技术网

Arrays 快速高效的数组查找和修改

Arrays 快速高效的数组查找和修改,arrays,lookup,Arrays,Lookup,我一直想知道以下两种方法中哪一种更快或更好 我目前的方法 我正在开发一个国际象棋游戏,棋子以数字(实际上是字节来保存内存)的形式存储到一维数组中。在数组中有一个与索引相对应的光标位置。访问数组中当前位置的工件很容易(piece=pieces[cursorPosition]) 问题在于,要获取用于检查移动是否有效的x和y值,需要除法和模运算符(x=cursorPosition%8;y=cursorPosition/8) 同样,当使用x和y来检查移动是否有效时(你必须这样做,因为这样做的原因会填满整

我一直想知道以下两种方法中哪一种更快或更好

我目前的方法 我正在开发一个国际象棋游戏,棋子以数字(实际上是字节来保存内存)的形式存储到一维数组中。在数组中有一个与索引相对应的光标位置。访问数组中当前位置的工件很容易(
piece=pieces[cursorPosition]

问题在于,要获取用于检查移动是否有效的x和y值,需要除法和模运算符(
x=cursorPosition%8;y=cursorPosition/8

同样,当使用x和y来检查移动是否有效时(你必须这样做,因为这样做的原因会填满整个页面),你必须做一些类似的事情-纯粹作为一个例子-
if片段[y*8+x]!=0:movePiece=False
。最明显的问题是必须执行
y*8+x
多次才能访问阵列

最终,这意味着获得一个片段很简单,但是获得x和y需要额外的内存和非常少的时间来计算每一轮

更传统的方法 使用二维数组,可以更轻松地实现上述过程,但工件查找现在变得更困难,并且使用了更多内存。(即
piece=pieces[cursorPosition[0]][cursorPosition[1]]
piece=pieces[x][y]

我不认为这是更快的,它肯定不会看起来更少的内存密集型

目标 我的最终目标是拥有尽可能快、占用内存最少的代码。这将是为unix终端开发的(如果我能想出如何使用Ansi转义序列表示不带颜色的片段,则可能是Windows CMD),我将使用安全的(使用协议和结构加密)我不知道人们会有多少内存,他们的计算机会有多快,他们的互联网连接会有多强

我也只是想学着用最好的方式去做,看看能不能做到

- 我想我的问题是:

假设涉及移动验证的计算稍微多一些(这意味着必须大量使用
y*8+x
),上述哪种方法更好


是否有一种方法既包含了一维数组的优点,又包含了二维数组的优点,并且没有我描述的那么多回退?

首先,您应该分析代码,以确保这确实是一个值得花费时间的瓶颈

其次,如果将位置表示为无符号字节,则将其分解为X和Y坐标将非常快。如果我们使用以下C代码:

int getX(unsigned char pos) {
   return pos%8;
}
我们使用gcc 4.8-O2获得以下组件:

getX(unsigned char):
    shrb    $3, %dil
    movzbl  %dil, %eax
    ret
getY(unsigned char):
    movl    %edi, %eax
    andl    $7, %eax
    ret
如果我们得到Y坐标,则:

int getY(unsigned char pos) {
   return pos/8;
}
我们使用gcc 4.8-O2获得以下组件:

getX(unsigned char):
    shrb    $3, %dil
    movzbl  %dil, %eax
    ret
getY(unsigned char):
    movl    %edi, %eax
    andl    $7, %eax
    ret

这个问题没有简单的答案;这完全取决于你花在优化上的时间

在某些体系结构上,二维阵列可能比一维阵列工作得更好。在其他体系结构上,位图整数可能是最好的

不要担心除法和乘法。 你在除以,调制,乘以8。 这个数字是二的幂,因此任何计算机都可以使用位运算来获得结果

  • (x*8)与(x>3)相同
这些操作通常在单个时钟周期内执行。在许多现代体系结构上,它们可以在不到一个时钟周期内执行(包括ARM体系结构)。 不用担心使用位运算符而不是*、%和/。如果您使用的编译器还不到十年,它会为您进行优化,并使用位操作

相反,你应该关注的是,你将多么容易发现一个举动是否合法,例如。这将帮助你的电脑播放器“快速思考”

如果您使用的是8*8阵列,那么通过检查是否只更改了x或y,您很容易看到城堡可以移动到哪里。如果检查皇后,则X必须与Y位置相同或移动的步数相同

如果使用一维数组,则也有优势

但就性能而言,使用16x16阵列或1x256阵列可能是一个非常好的主意。 用0x80值填充整个数组(例如“非法位置”)。然后用0x00填充法律字段

如果使用1x256数组,可以检查索引的第3位和第7位。如果设置了其中任何一个,则该位置位于板外。 可以通过以下方式进行测试:

if(position & 0x88)
{
    /* move is illegal */
}
else
{
    /* move is legal */
}
。。。或者

if(0 == (position & 0x88))
{
    /* move is legal */
}
“position”(索引)应该是一个无符号字节(uint8_t in C)。这样,您就不必担心指向缓冲区之外

有些人通过使用64位位图整数来优化他们的象棋引擎。 虽然这有利于快速比较位置,但也有其他缺点;例如,检查骑士的举动是否合法。 不过,说哪一个更好并不容易

我个人认为,一般来说,一维数组可能是最好的方法。 我建议您熟悉(非常熟悉)AND、OR、XOR、位移位和旋转


有关更多信息,请参见。

首先,您翻转了x和y。x=pos%8用于获取该行中的x索引,y=pos/8用于获取该行。我知道我可以写一个方法,但那会更慢,而且我还必须做很多,因为当我检查一堆位置,看它们是否包含可以攻击国王的部分时,例如,我必须做两个循环,就像在2d数组中一样,但是对于每个索引,我也必须一遍又一遍地重复你上面写的方法。哦,也许你只是错误地命名了这些方法。。。盖蒂·雷图