Algorithm “矩阵与算法”;螺旋形;
我想问一下是否有一些算法准备好了,这让我可以这样做:我有一个矩阵m(col)xn(row)和mxn元素。我想给这个元素定位,从中心开始,旋转成螺旋,例如,对于矩阵3x3,我定义了9个元素:Algorithm “矩阵与算法”;螺旋形;,algorithm,delphi,matrix,delphi-xe2,spiral,Algorithm,Delphi,Matrix,Delphi Xe2,Spiral,我想问一下是否有一些算法准备好了,这让我可以这样做:我有一个矩阵m(col)xn(row)和mxn元素。我想给这个元素定位,从中心开始,旋转成螺旋,例如,对于矩阵3x3,我定义了9个元素: 5 6 7 4 9 8 3 2 1 8 9 10 1 7 12 11 2 6 5 4 3 3 4 7 8 10 9 6 5 2 1 对于una矩阵4 x 3,我有12个元素,是否定义: 5 6
5 6 7
4 9 8
3 2 1
8 9 10 1
7 12 11 2
6 5 4 3
3 4
7 8
10 9
6 5
2 1
对于una矩阵4 x 3,我有12个元素,是否定义:
5 6 7
4 9 8
3 2 1
8 9 10 1
7 12 11 2
6 5 4 3
3 4
7 8
10 9
6 5
2 1
再一次,矩阵5x2 i有10个元素定义如下:
5 6 7
4 9 8
3 2 1
8 9 10 1
7 12 11 2
6 5 4 3
3 4
7 8
10 9
6 5
2 1
等等。
我基本上已经解决了定义一个由m x n个元素组成的整数数组并手动加载值的问题,但一般来说,我喜欢由算法自动生成的矩阵。
谢谢谁能帮我找到一些东西,非常感谢
更新
这段代码,做得很精确,我想有,但不是在delphi中;只是我需要从1开始,而不是从0开始。对我来说重要的是,它对任何矩阵m x n都有效。谁帮我用德尔菲翻译
(defun spiral (rows columns)
(do ((N (* rows columns))
(spiral (make-array (list rows columns) :initial-element nil))
(dx 1) (dy 0) (x 0) (y 0)
(i 0 (1+ i)))
((= i N) spiral)
(setf (aref spiral y x) i)
(let ((nx (+ x dx)) (ny (+ y dy)))
(cond
((and (< -1 nx columns)
(< -1 ny rows)
(null (aref spiral ny nx)))
(setf x nx
y ny))
(t (psetf dx (- dy)
dy dx)
(setf x (+ x dx)
y (+ y dy)))))))
> (pprint (spiral 6 6))
#2A ((0 1 2 3 4 5)
(19 20 21 22 23 6)
(18 31 32 33 24 7)
(17 30 35 34 25 8)
(16 29 28 27 26 9)
(15 14 13 12 11 10))
> (pprint (spiral 5 3))
#2A ((0 1 2)
(11 12 3)
(10 13 4)
(9 14 5)
(8 7 6))
(取消螺旋(行-列)
(do((N(*行和列))
(螺旋线(生成数组(列出行和列):初始元素nil))
(dx1)(dy0)(x0)(y0)
(i0(1+i)))
(=i N)螺旋线)
(setf(aref螺旋y x)i)
(让((nx(+x dx))(ny(+y-dy)))
(续)
((和(<-1 nx列)
(<-1行)
(空(aref螺旋线ny nx)))
(setf x nx)
y(纽约))
(t(psetf-dx(-dy)
dy(dx)
(设定值x(+x dx)
y(+y y()()()))
>(pprint(螺旋6))
#2A((01 2 3 4 5)
(19 20 21 22 23 6)
(18 31 32 33 24 7)
(17 30 35 34 25 8)
(16 29 28 27 26 9)
(15 14 13 12 11 10))
>(pprint(螺旋5-3))
#2A((0 1 2)
(11 12 3)
(10 13 4)
(9 14 5)
(8 7 6))
再次非常感谢。以下是您试图实现的已注释JavaScript实现
// return an array representing a matrix of size MxN COLxROW
function spiralMatrix(M, N) {
var result = new Array(M * N);
var counter = M * N;
// start position
var curCol = Math.floor((M - 1) / 2);
var curRow = Math.floor(N / 2);
// set the center
result[(curRow * M) + curCol] = counter--;
// your possible moves RIGHT, UP, LEFT, DOWN * y axis is flipped
var allMoves = [[1,0], [0,-1], [-1,0], [0,1]];
var curMove = 0;
var moves = 1; // how many times to make current Move, 1,1,2,2,3,3,4,4 etc
// spiral
while(true) {
for(var i = 0; i < moves; i++) {
// move in a spiral outward counter clock-wise direction
curCol += allMoves[curMove][0];
curRow += allMoves[curMove][1];
// naively skips locations that are outside of the matrix bounds
if(curCol >= 0 && curCol < M && curRow >= 0 && curRow < N) {
// set the value and decrement the counter
result[(curRow * M) + curCol] = counter--;
// if we reached the end return the result
if(counter == 0) return result;
}
}
// increment the number of times to move if necessary UP->LEFT and DOWN->RIGHT
if(curMove == 1 || curMove == 3) moves++;
// go to the next move in a circular array fashion
curMove = (curMove + 1) % allMoves.length;
}
}
//返回表示大小为MxN COLxROW的矩阵的数组
函数矩阵(M,N){
var结果=新数组(M*N);
var计数器=M*N;
//起始位置
var curCol=数学楼层((M-1)/2);
var curRow=数学楼层(N/2);
//居中
结果[(curRow*M)+curCol]=计数器--;
//可能的向右、向上、向左、向下移动*y轴已翻转
var allMoves=[[1,0],[0,-1],-1,0],[0,1];
var-curMove=0;
var moves=1;//当前移动次数,1,1,2,2,3,3,4,4等
//螺旋形
while(true){
对于(变量i=0;i=0&&curCol=0&&curRow向左和向下->向右移动的次数
如果(curMove==1 | | curMove==3)移动++;
//以圆形阵列方式转到下一步
curMove=(curMove+1)%allMoves.length;
}
}
这段代码并不是最有效的,因为它天真地沿着螺旋走,而没有首先检查它所走的位置是否有效。在尝试设置当前位置的值之前,它只检查当前位置的有效性 好了!!!在出现一些语法错误之后 上,我运行了一些测试,它似乎工作良好。我认为您仍然可以在那里看到输出并自己运行它 我在代码中添加了一些注释。足以理解其中的大部分。主导航系统有点难以解释。简单地说,做一个螺旋是朝第一个方向走1次,第二个方向走1次,第三个方向走2次,第四个方向走2次,第五个方向走3次,第3次,第4次,第4次,第5次,第5次,依此类推。我使用我所称的
种子
和步骤
来获得这种行为
program test;
var
w, h, m, n, v, d : integer; // Matrix size, then position, then value and direction.
spiral : array of array of integer; // Matrix/spiral itself.
seed, step : integer; // Used to travel the spiral.
begin
readln(h);
readln(w);
setlength(spiral, h, w);
v := w * h; // Value to put in spiral.
m := trunc((h - 1) / 2); // Finding center.
n := trunc((w - 1) / 2);
d := 0; // First direction is right.
seed := 2;
step := 1;
// Travel the spiral.
repeat
// If in the sub-spiral, store value.
if ((m >= 0) and (n >= 0) and (m < h) and (n < w)) then
begin
spiral[m, n] := v;
v := v - 1;
end;
// Move!
case d of
0: n := n + 1;
1: m := m - 1;
2: n := n - 1;
3: m := m + 1;
end;
// Plan trajectory.
step := step - 1;
if step = 0 then
begin
d := (d + 1) mod 4;
seed := seed + 1;
step := trunc(seed / 2);
end;
until v = 0;
// Print the spiral.
for m := 0 to (h - 1) do
begin
for n := 0 to (w - 1) do
begin
write(spiral[m, n], ' ');
end;
writeln();
end;
end.
屈服
3 4
7 8
10 9
6 5
2 1
基于经典。支持非平方矩阵:
program SpiralMatrix;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TMatrix = array of array of Integer;
procedure PrintMatrix(const a: TMatrix);
var
i, j: Integer;
begin
for i := 0 to Length(a) - 1 do
begin
for j := 0 to Length(a[0]) - 1 do
Write(Format('%3d', [a[i, j]]));
Writeln;
end;
end;
var
spiral: TMatrix;
i, m, n: Integer;
row, col, dx, dy,
dirChanges, visits, temp: Integer;
begin
m := 3; // columns
n := 3; // rows
SetLength(spiral, n, m);
row := 0;
col := 0;
dx := 1;
dy := 0;
dirChanges := 0;
visits := m;
for i := 0 to n * m - 1 do
begin
spiral[row, col] := i + 1;
Dec(visits);
if visits = 0 then
begin
visits := m * (dirChanges mod 2) + n * ((dirChanges + 1) mod 2) - (dirChanges div 2) - 1;
temp := dx;
dx := -dy;
dy := temp;
Inc(dirChanges);
end;
Inc(col, dx);
Inc(row, dy);
end;
PrintMatrix(spiral);
Readln;
end.
3 x 3:
1 2 3
8 9 4
7 6 5
1 2 3 4
10 11 12 5
9 8 7 6
1 2
10 3
9 4
8 5
7 6
4 x 3:
1 2 3
8 9 4
7 6 5
1 2 3 4
10 11 12 5
9 8 7 6
1 2
10 3
9 4
8 5
7 6
2 x 5:
1 2 3
8 9 4
7 6 5
1 2 3 4
10 11 12 5
9 8 7 6
1 2
10 3
9 4
8 5
7 6
尽管问题已经得到了回答,但这是另一种解决方案(可以说更简单)。 该解决方案是用python编写的(使用numpy实现双向数组),但可以很容易地进行移植 基本思想是使用已知步数(m*n)作为结束条件, 为了在每次迭代中正确计算循环的下一个元素:
将numpy导入为np
def螺旋(m,n):
“”“返回形状为(m,n)的int螺旋numpy数组。”
a=np.空((m,n),int)
i、 i0,i1=0,0,m-1
j、 j0,j1=0,0,n-1
对于范围内的k(m*n):
a[i,j]=k
如果i==i0和j0,那么在我看来,您的算法还没有很好地定义。我希望5x2矩阵是((67)(58)(49)(310)(21))。我支持David。为什么我从不同的地方开始?每次都应该在同一个角落。我不懂你的算法。这是不一致的。例如3x3的经典螺旋算法应该是:(1 2 3)(8 9 4)(7 6 5)
。您好,很可能我没有正确地告诉“螺旋”。这只是为了给人一个想法,矩阵中的数字被放置在设计一个螺旋上,例如,对于6个数字,它从6开始到1:6,5,4,3,2,1。元素6被放置在矩阵的中心,矩阵的索引以螺旋的形式从左向右旋转。有如例子中那样的结果。再次原谅我英语不好。这样设置元素的矩阵应用于随机数。首先,你可以在这里检查,非常感谢Joanis。这个解决方案是关于我搜索的,它工作得非常好。再次感谢你;感谢所有其他帮助我的东西。当我用2x2和2x2进行测试时,它产生了一些奇怪的螺旋4x3@kobik:是的,并不是所有的案例都给出了我们真正可以称之为螺旋的东西。中心由楼层((高度-1)/2)
和楼层((宽度-1)/2)
定义,方向顺序从“r”开始