Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.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
Algorithm “矩阵与算法”;螺旋形;_Algorithm_Delphi_Matrix_Delphi Xe2_Spiral - Fatal编程技术网

Algorithm “矩阵与算法”;螺旋形;

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

我想问一下是否有一些算法准备好了,这让我可以这样做:我有一个矩阵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  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”开始