Ruby 在一个由外而内的螺旋中循环

Ruby 在一个由外而内的螺旋中循环,ruby,algorithm,spiral,Ruby,Algorithm,Spiral,我希望通过一个类似于的矩阵进行循环,但是从外到内循环,而不是从内到外循环。有谁能帮我找到一个好方法来处理任意大小的矩阵,最好是Ruby 例如: 在3x4矩阵中,我想从[0,0]开始向右移动,然后在到达[3,0]时向下移动,在[3,2]处向左移动,以此类推 [0,0] [1,0] [2,0] [3,0] [0,1] [1,1] [2,1] [3,1] [0,2] [1,2] [2,2] [3,2] 移动顺序如下所示: 0 1 2 3 9 10 11 4 8 7 6 5 其结果是:

我希望通过一个类似于的矩阵进行循环,但是从外到内循环,而不是从内到外循环。有谁能帮我找到一个好方法来处理任意大小的矩阵,最好是Ruby

例如: 在3x4矩阵中,我想从[0,0]开始向右移动,然后在到达[3,0]时向下移动,在[3,2]处向左移动,以此类推

[0,0] [1,0] [2,0] [3,0]
[0,1] [1,1] [2,1] [3,1]
[0,2] [1,2] [2,2] [3,2]
移动顺序如下所示:

0  1  2  3
9  10 11 4
8  7  6  5
其结果是:

[0,0], [1,0], [2,0], [3,0], [3,1], [3,2], [2,2], [1,2], [0,2], [0,1], [1,1], [2,1]

在不丧失一般性的情况下,让我们将数组编写为:

arr = [
  [ 1,  2,  3, 4,],
  [12, 13, 14, 5,],
  [11, 16, 15, 6,],
  [10,  9,  8, 7,]
]
预期的结果是:

[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
我将使用助手:

def rotate_anticlockwise(arr)
  arr.map(&:reverse).transpose
end
例如:

rotate_anticlockwise(arr)
  #=> [[4,  5,  6, 7],
  #    [3, 14, 15, 8],
  #    [2, 13, 16, 9],
  #    [1, 12, 11, 10]] 
我们现在可以按如下方式计算所需结果:

out = []
a = arr.map(&:dup)
while a.any?
  out.concat(a.shift)
  a = rotate_anticlockwise(a)
end
out
  # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] 
这是一个按顺时针方向从外到内打印2D矩阵的程序

int n = 2, m = 5;
    int arr[2][5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    int top = 0, bottom = n-1, right = m-1, left = 0, i=0, j=0;

    printf("%d ", arr[i][j]);

    while(1){
        if(top>bottom || left>right) break;


        if(bottom==top){
            for(j=left; j<=right; j++)
                printf("%d ", arr[top][j]);
            break;
        }

        if(right==left){
            for(i=top; i<=bottom; i++)
                printf("%d ", arr[left][i]);
            break;
        }

        int first = 1;
        while(j<=right){
            if(first){
                j++;
                first = 0;
                continue;
            }

            printf("%d ", arr[i][j]);
            j++;
        }
        j--; right--;

        first = 1;
        while(i<=bottom){
            if(first){
                i++;
                first = 0;
                continue;
            }           

            printf("%d ", arr[i][j]);
            i++;
        }
        i--; bottom--;

        first = 1;
        while(j>=left){
            if(first){
                j--;
                first = 0;
                continue;
            }

            printf("%d ", arr[i][j]);
            j--;
        }
        j++; left++;

        first = 1;
        while(i>=top+1){
            if(first){
                i--;
                first = 0;
                continue;
            }

            printf("%d ", arr[i][j]);
            i--;
        }
        i++; top++;
    }
int n=2,m=5;
int arr[2][5]={1,2,3,4,5,6,7,8,9,10};
int top=0,bottom=n-1,right=m-1,left=0,i=0,j=0;
printf(“%d”,arr[i][j]);
而(1){
如果(顶部>底部| |左侧>右侧)中断;
如果(底部==顶部){

对于(j=left;j此方法执行您所需的操作,它循环通过外部螺旋,然后递归调用自身以循环通过内部螺旋

def inward_spiral(height, width, current_height, current_width)
  if height <= 0 || width <= 0
    return
  end

  # Right
  (width-1).times do
      puts "[#{current_width}, #{current_height}]"
      current_width += 1 
  end

  # Down
  (height-1).times do
    puts "[#{current_width}, #{current_height}]"
    current_height += 1
  end

  # Left
  if height > 1
      (width-1).times do 
          puts "[#{current_width}, #{current_height}]"
          current_width -= 1 
      end
  end

  # Up
  if width > 1
      (height-2).times do
          puts "[#{current_width}, #{current_height}]"
          current_height -= 1
      end
  end

  puts "[#{current_width}, #{current_height}]"
  inward_spiral(height-2, width-2, current_width + 1, current_height)
end

这是一个一直让我着迷的问题。@CarySwoveland有一个诀窍,使它在Ruby中变得非常优雅。这里是一个单线方法:

def spiral(matrix)
  matrix.empty? ? [] : matrix.shift + spiral(matrix.transpose.reverse)
end

arr = [[ 1,  2,  3, 4,],
       [12, 13, 14, 5,],
       [11, 16, 15, 6,],
       [10,  9,  8, 7,]]

spiral(arr)

# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
然而,这种方法的一个缺陷是它改变了原始矩阵arr:

arr

# => [[12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]

这其中有几个答案也值得一看。

我提出了一个ruby方法来解决这个问题,虽然有点冗长,但应该很容易理解它是如何工作的:如果有人仍然关心重复的,那么它们就是:并且-除了它们没有给出ruby代码之外,我发现这两个方面的大多数答案都非常令人满意对于这个问题。欢迎来到Stack Overflow。向我们展示您在试图解决问题时所做的尝试非常重要。这使我们能够更正您自己代码中的错误,而不是在现有代码中强行插入不熟悉/陌生的代码。这是假设您已经尝试了一些东西,而不仅仅是希望某个人ne会为你写这篇文章。@theTinMan fair point。我使用的是这里概述的基本算法,但我知道Ruby必须有一种更优雅的方法来解决这个问题。我将在以后的问题中发布我的代码!可能是重复的谢谢大家,看到你们不同的解决方案非常有趣。最后我使用这个解决方案,因为我喜欢它使用转置来解决它的方式。有趣的是…它就像是切片顶层然后旋转矩阵?所以它就像一个块和奶酪,你总是切片顶部然后旋转奶酪块…现在它不就是
O(n*m*k)
其中k是min(n,m),最好的方法应该是
O(n*m)
?…顺便问一下,如果现在的问题是“以螺旋方式填充一个n*m的空矩阵”,该怎么办?这个问题的答案中的矩阵就是这样的@太極者無極而生, 我喜欢你的奶酪块。让我想想你说的话。我明天会尽力回复。很高兴看到一个简短的一行!很好的一行,O-I。我喜欢你消除我的
反向映射的方式(
矩阵。反向。转置也有效)l和递归的使用。如果原始矩阵不进行变异,只需添加
def spiral\u starter(矩阵);spiral(矩阵映射(&:dup));end
。你应该框出你的答案。漂亮的图形。你在找这个:
?似乎没有向左向上的字符,这是奇数。
arr

# => [[12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]