我保证是一个完美的方阵。我想从矩阵的中心开始,在这种情况下它将是matrix[2][2]
,我知道如何计算中心(int)(dimensions / 2)
。我需要在以下向外螺旋模式中输出数组的内容。当然,算法应该适用于任何完美的方阵。我不确定这个算法是否已经存在,我不想重新发明轮子。
int dimensions / 2;
21 22 23 24 25
20 7 8 9 10
19 6 1 2 11
18 5 4 3 12
17 16 15 14 13
此示例的输出应为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
答案 0 :(得分:5)
让我们先确定模式..
偶数正方形矩阵,例如:4x4
07 > 08 > 09 > 10
^ v
06 (01)> 02 11
^ v v
05 < 04 < 03 12
v
[16]< 15 < 14 < 13
Starting Point: [2, 2] ~ [SIZE/2, SIZE/2]
Ending Point: [4, 1] ~ [SIZE, 1]
Chains: Count(K-chain)=2 for K = 1..(SIZE-2)
+ 3 for Count = SIZE-1
奇数方形矩阵,例如:5x5
21 > 22 > 23 > 24 >[25]
^
20 07 > 08 > 09 > 10
^ ^ v
19 06 (01)> 02 11
^ ^ v v
18 05 < 04 < 03 12
^ v
17 < 16 < 15 < 14 < 13
Starting Point: [2, 2] ~ [⌊SIZE/2⌋, ⌊SIZE/2⌋]
Ending Point: [1, 5] ~ [1, SIZE]
Chains: Count(K-chain)=2 for K = 1..(SIZE-2)
+ 3 for Count = SIZE-1
void print_spiral (int ** matrix, int size)
{
int x = 0; // current position; x
int y = 0; // current position; y
int d = 0; // current direction; 0=RIGHT, 1=DOWN, 2=LEFT, 3=UP
int c = 0; // counter
int s = 1; // chain size
// starting point
x = ((int)floor(size/2.0))-1;
y = ((int)floor(size/2.0))-1;
for (int k=1; k<=(size-1); k++)
{
for (int j=0; j<(k<(size-1)?2:3); j++)
{
for (int i=0; i<s; i++)
{
std::cout << matrix[x][y] << " ";
c++;
switch (d)
{
case 0: y = y + 1; break;
case 1: x = x + 1; break;
case 2: y = y - 1; break;
case 3: x = x - 1; break;
}
}
d = (d+1)%4;
}
s = s + 1;
}
}
答案 1 :(得分:4)
因为这有点像家庭作业,所以没有代码或直接答案,而只是一些提示:
您可以将此视为乌龟问题:
让m
移动1
单元格,r
在螺旋方向(CW或CCW)上旋转90
度。然后螺旋可以被编码为形成这种模式的一系列乌龟命令(从起点开始):
m,r,m,r,
m,m,r,m,m,r,
m,m,m,r,m,m,m,r,
m,m,m,m,r,m,m,m,m,r,
m,m,m,m,m,r
你可以看到你开始1x移动然后旋转两次重复你切换到2x移动,2移动切换到3x移动,......等等。这可以通过几个for循环来完成(或者仅通过一些具有适当的迭代来完成,并且当达到矩阵数量的单元格时停止...或者端点角落被击中)
您需要处理偶数/奇数矩阵
奇数矩阵大小的是容易的中间点。对于均匀尺寸,它有点复杂。如果你使用CW旋转然后使用向下舍入分割结果将大小减半,并从向右移动开始。 (如果您需要不同的螺旋线,则需要将+1
添加到x
和/或y
并更改起始方向,以便螺旋线保持居中。
所以如果你得到了偶数大小的矩阵,那么如果你得到奇数大小,那么最后一次移动是两次,那么最后一次移动只有一次(就像在这个例子中一样)
轮换强>
将方向存储为2D矢量。例如d=(+1,0)
意味着正确。要旋转2D矢量,您只需交换坐标并取消一个轴(哪一个意味着CW / CCW)。例如(x,y) -> (y,-x)
<强>运动强>
也将当前位置存储为2D矢量。该动作只是向其添加当前方向向量。
解决这个问题很开心......
答案 2 :(得分:0)
int radius = 0;
int i = centerX;
int j = centerY;
Debug.Log("i=" + i + "; j=" + j);
++i;
radius += 2;
while ((i < dimm) && (i >= 0))
{
for (int c = j; j < c + radius; j++)
Debug.Log("i=" + i + "; j=" + j);
--j;
--i;
for (int c = i; i > c - radius + 1; i--)
Debug.Log("i=" + i + "; j=" + j);
if (i < 0)
break;
else
Debug.Log("i=" + i + "; j=" + j);
--j;
for (int c = j; j > c - radius; j--)
Debug.Log("i=" + i + "; j=" + j);
++i;
++j;
for (int c = i; i < c + radius; i++)
Debug.Log("i=" + i + "; j=" + j);
radius += 2;
}
此代码将从自定义中心(CenterX,CenterY)输出逆时针方形矩阵(dimm X dimm)索引;如果它来自矩阵大小,最终会结束。
答案 3 :(得分:0)
bool IsIterationComplete(int iteration, int nCenter, std::vector<std::vector<bool>>& vVisited)
{
int nHigh = nCenter+iteration;
int nLow = nCenter-iteration;
//cout<<endl<<"High "<<nHigh<<"Low "<<nLow<<endl;
for(int i=nLow;i<=nHigh;i++)
{
if(!vVisited[nHigh][i] || !vVisited[nLow][i])
return false;
}
for(int i=nLow;i<=nHigh;i++)
{
if(!vVisited[i][nHigh] || !vVisited[i][nLow])
return false;
}
return true;
}
void PrintSpiral(std::vector<std::vector<int>>& vMat,std::vector<std::vector<bool>>& vVisited, int row, int col, int nCenter, int iteration)
{
cout<<vMat[row][col];
vVisited[row][col]=true;
if(row==0 && col==0)
return;
if(IsIterationComplete(iteration,nCenter,vVisited))
iteration++;
//cout<<endl<<"row "<<row<<" column "<<col<<"Iteration "<<iteration<<endl;
//left
if(col-1>=0 && !vVisited[row][col-1] && col-1>=nCenter-iteration)
{
cout<<"Left "<<endl;
PrintSpiral(vMat,vVisited,row,col-1,nCenter,iteration);
}
//Down
if((row+1)<vMat.size() && !vVisited[row+1][col] && row+1<=nCenter+iteration)
{
cout<<"Down "<<endl;
PrintSpiral(vMat,vVisited,row+1,col,nCenter,iteration);
}
//right
if((col+1)<vMat.size() && !vVisited[row][col+1] && col+1<=nCenter+iteration)
{
cout<<"Right "<<endl;
PrintSpiral(vMat,vVisited,row,col+1,nCenter,iteration);
}
//up
if(row-1>=0 && !vVisited[row-1][col] && row-1>=nCenter-iteration)
{
cout<<"Up "<<endl;
PrintSpiral(vMat,vVisited,row-1,col,nCenter,iteration);
}
}
int main (int argc, const char * argv[])
{
int nCount=1;
std::vector<std::vector<int>> vMat;
std::vector<std::vector<bool>> vVisited;
for(int i=0; i<7; i++)
{
std::vector<int> row;
std::vector<bool> visitedRow;
for(int j=0; j<7; j++)
{
row.push_back(nCount);
cout<<nCount<<'\t';
nCount++;
visitedRow.push_back(false);
}
cout<<'\n';
vMat.push_back(row);
vVisited.push_back(visitedRow);
}
cout<<'\n';
PrintSpiral(vMat,vVisited,vMat.size()/2,vMat.size()/2,vMat.size()/2,0);
return 0;
}