蛇形矩阵是数组操中较为经典的案例之一,今天便来分析一下此矩阵的分析与代码阐述。实现基于C++与一维数组。
蛇形矩阵有许多的变种类型,不过分析方法都是大相径庭的。
如下图是一张5行的蛇形矩阵,将以此为例进行分析
已经将每个数字做了编号,并画出了各项之间的差值。
分析第一行,将“a0、a1、a2、a3、a4”视为一个数列,易得第一行的递推公式为:
(第一项下标为1)
注:是递推公式哦,不用用来算首项
或者使用从零开始编号则得到:
这意味着从“a1”开始每一项的值都和前一项以及“n”的值有关,或者说首项“a0”的前一项为“0”那么我们可以得出每一行的计算方式(伪代码)
i //当前行计算的元素下标
ele_num_row //当前行的元素个数
ele //当前计算元素的值
ele_last //上一个元素的值
ele_first //行首元素的值
for(i = 0; i < ele_num_row; i++){
if(!i) ele = ele_first //行首元素独立判断
else ele = ele_last + (i + 1) //实现递推公式
}
好解决完行之后对列下刀,和行分析的方法类似,将“a0、a5、a9、a12、a14”视为数列,易得第一列的递推公式为:
(从第一项开始)
或者使用从零开始编号则得到:
好,现在拿到了行与列递推公式,下一步便是想办法将上文计算一行的方式应用到所有行。
不过在此之前必须先解决一个问题:每一行都有自己的递推公式,而且将递推公式中的“n”转化成递推过程中的实际值时,其值往往会和当前运算的行挂钩。为了程序的可读性较高,将每行的“n”命名为变量:row_step(其实可以和行标记合并);同时添加行标记变量:line_feed。
下面提供思路
//沿用的变量
i //当前行计算的元素下标
ele_num_row //当前行的元素个数
ele //当前计算元素的值
ele_last //上一个元素的值
ele_first //行首元素的值
num //蛇形矩阵的阶数
line_feed //当前行
row_step //每行第二个元素和第一个元素的差值
while(1){
if(line_feed >= num) break;
for(i = 0; i < ele_num_row; i++){ //这里执行一次行计算
if(!i) ele = ele_first //行首元素独立判断
else ele = ele_last + (i + row_step) //实现递推公式
}
ele_num_row = num - line_feed; //更新行元素数量
ele_row_first += row_step; //更新行首元素
row_step++; //每行步进量的设置
}
好,到此为止我们已经成功解决掉蛇形矩阵了,接下来便是将代码规整实现。先附上源代码
//蛇形矩阵
#include<iostream>
using namespace std;
void GetResult(int Num, int * pResult);
int main()
{
int* pResult{ nullptr }; //初始化数组
int Num{ 0 }; //初始化输入变量
cin >> Num; //读取输入遍量
GetResult(Num, pResult);
system("Pause");
return 0;
}
void GetResult(int Num, int * pResult)
{
unsigned int num_snake{ 0 }; //数组中元素的个数
unsigned int line_feed{ 0 }; //当前行---换行变量
unsigned int ele_row_first{ 1 }; //每行的第一个元素值---初始化为1(第一行)
unsigned int ele_num_row{ Num }; //每行元素的个数
unsigned int ele_sum{ 0 }; //已写入的元素个数
unsigned int row_step{ 1 }; //行元素步进量---第一行 --- 后续需要 + i
unsigned int i{ 0 }; //遍历变量
/*第一步准备---元素个数的计算与数组的创建*/
num_snake = ((Num + 1) * Num) / 2; //求和公式---获取数组内的元素个数
pResult = new int[num_snake] { 0 }; //获取生成的数组长度
/*第二步---依据计算公式填参*/
while (1) {
if (line_feed >= Num) break; //当所有行都写入完毕时退出
for (i = 0; i < ele_num_row; i++, ele_sum++) { //For循环
if (!i) pResult[ele_sum] = ele_row_first; //要区分每行的第一个元素和后续元素,因为计算方式不同
else pResult[ele_sum] = pResult[ele_sum - 1] + row_step + i;
cout << static_cast<int>(pResult[ele_sum]) << "\t"; //输出一行元素
}
cout << endl; //换行
line_feed++; //换行标志---已经写入的行数
ele_num_row = Num - line_feed; //每行元素的个数---用于for循环每行的填值
ele_row_first += row_step; //每行首元素的重置
row_step++; //每行步进量的设置
}
//下面这段是输出用的---如果不在填数的过程中输出这步其实可以不用
// line_feed = 0;
// ele_num_row = Num;
// for(i = 0; i < ele_sum; i++){
// if(i == ele_num_row){
// cout << endl;
// line_feed++;
// ele_num_row += Num - line_feed;
// }
// cout << pResult[i] << " ";
// }
}