题目描述:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
例如,如果输入4*4的矩阵:
;;;。
则依次打印出数字:
81216151。
解题思路:
本题为了将矩阵顺时针螺旋输出。如下图所示,对每一圈而言,就是先获取第一行,再拿到最后一列,再拿最后一行,最后拿第一列,确定好对应的位置关系,用4个循环即可实现。考虑到可能会碰上行列不一致的情况,所以圈数要取行数和列数最小值的一半。另外,我发现当矩阵为3行4列时,第2圈只有6和7,此时用常规代码会将6重复获取两次,为了避免该情况发生,用mask作为数据是否获取的位置标识。
测试代码:
#includeiostream
#includevector
#includestring
usingnamespacestd;
#definemin(a,b)(ab?a:b)
vectorintgetSpiralData(vectorvectorintinputs);
intmain()
{
//输入矩阵
vectorvectorintinputs={
{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16},{17,18,19,20},{21,22,23,24}
};
//输出输入
cout"输入:"endl;
for(inti=0;iinputs.size();++i)
{
for(intj=0;jinputs[0].size();++j)
{
coutinputs[i][j]"";
}
coutendl;
}
//输出螺旋矩阵
vectorintoutput=getSpiralData(inputs);
//输出结果
cout"输出:"endl;
for(inti=0;ioutput.size();++i)
{
coutoutput[i]"";
}
coutendl;
system("pause");
return0;
}
//输出螺旋矩阵
vectorintgetSpiralData(vectorvectorintinputs)
{
//定义行列数
introw=inputs.size();
intcol=inputs[0].size();
//定义起始点
intstartr=0;
intstartc=0;
//定义圈数,offset=0为第一圈
intoffset=0;
//初始化输出
vectorintoutputs;
//初始化掩膜,用来避免数据重复存储
vectorvectorboolmask(row,vectorbool(col,false));
//当行列不一致时,取最小值/2作为圈数
intturns=(min(row,col)+1)/2;
//单圈存储
while(turns)
{
inti=startr;
intj=startc;
//顺时针第一行
for(j=startc;jcol-offset;j++)
{
if(!mask[i][j])
{
outputs.push_back(inputs[i][j]);
mask[i][j]=true;
}
}
j--;
//顺时针最后一列
for(i=startr+1;irow-offset;i++)
{
if(!mask[i][j])
{
outputs.push_back(inputs[i][j]);
mask[i][j]=true;
}
}
i--;
//顺时针最后一行
for(j=col-offset-2;j=startc;j--)
{
if(!mask[i][j])
{
outputs.push_back(inputs[i][j]);
mask[i][j]=true;
}
}
j++;
//顺时针第一列
for(i=row-offset-2;istartr;i--)
{
if(!mask[i][j])
{
outputs.push_back(inputs[i][j]);
mask[i][j]=true;
}
}
i++;
//圈数步进,下一圈的初始点的x和y值均+1
offset++;
startr++;
startc++;
turns--;
}
returnoutputs;
}