任务是:开发一个函数 int is_tridiagonal (int *mat,int n); mat 是一个 nxn 方阵。如果 mat 是三对角矩阵,该函数应返回 1,否则返回 0。
三对角矩阵(除了“三个主要”对角线之外的所有地方都是 0)
使用基本方法完成任务,使用循环遍历第 i 行,第 j 列的元素
但是您需要以某种方式不使用这些 i、j 并使用指针解决问题
一般来说,值得将我的周期转换成这样的东西,我不明白该怎么做
诠释* p; ... for (p = &a[0][0]; p <= &a[NUM_ROWS-1][NUM_COLS-1]; p++)
#include <stdio.h>
#define cols 6
void user_matrix(int matrix[cols][cols]);
void matrix_outp(int matrix[cols][cols]);
int is_tridiagonal(int matrix[cols][cols]);
int main() {
int matrix[cols][cols];
user_matrix(matrix);
matrix_outp(matrix);
printf("%d", is_tridiagonal(matrix));
}
void user_matrix(int matrix[cols][cols]) {
for (int i = 0; i < cols; i++) {
for (int j = 0; j < cols; j++) {
printf("Enter matrix[%d][%d]: ", i + 1, j + 1);
scanf_s("%d", &matrix[i][j]);
}
printf("\n");
}
}
void matrix_outp(int matrix[cols][cols])
{
for (int i = 0; i < cols; i++)
{
for (int j = 0; j < cols; j++)
{
printf("%6d", matrix[i][j]);
}
printf("\n");
}
}
// перебор элементов матрицы и проверка на 0
int is_tridiagonal(int matrix[cols][cols]) {
int schet = 0;
// выше главной и следующей после нее
for (int i = 0; i < cols - 1; i++)
{
for (int j = i + 2; j < cols; j++) {
if (matrix[i][j] != 0)
schet++;
}
}
// ниже главной и следующей после нее
for (int i = 1; i < cols; i++)
{
for (int j = 0; j < i - 1; j++)
{
if (matrix[i][j] != 0)
schet++;
}
}
// 3 главные по центру
for (int i = 0; i < cols; i++) {
for (int j = 0; j < cols; j++) {
if (i == j || i == (j - 1) || i == (j + 1)) {
if (matrix[i][j] == 0) {
schet++;
}
}
}
}
if (schet == 0)
printf("Trexdiagonal");
else
printf("NETrexdiagonal");
}
我们可以将矩阵转换为点
int* pointer = &matrix[0][0];
并像一维数组一样工作。如果我们有一个 5x5 矩阵,N=5:
那是一个一维数组:
如果我们分析其他大小的矩阵,我们会注意到一个模式:
2xA, 3xB, 3xA, 3xB, 3xA, 3xB, 3xA, 3xB, 2xA
,其中 A 为 1,B 为 0,2xA 是连续的两个 A,依此类推。我们可以注意到 A 重复了 3 次,除了开头和结尾,因为有三个对角线。还有 3 次 B,考虑其他示例后,我们得到 - N-2 次连续(在第一行和最后一行)。
因此,我们知道从哪里开始 - 从 3 个元素(2 个索引)开始,要采取多少步 - 检查 N-2 个元素,它们是 0,并跳过 3 个元素(总共 N + 1 个),我们也知道从哪里开始停止——这取决于倒数第二个元素
&matrix[N-1][N-2]
!编辑:
@DmitryK注意到我没有正确构建条件,这仅适用于 N=5,并且我没有立即将指向矩阵的指针传递给函数。
我已经更改了我的代码。现在该函数立即获取一个指向矩阵的指针,但不再使用任何其他指针。我检查了 4,5,6 个方阵,“3xA”从索引开始
size
,然后递增size+1
.这个想法是我们现在如何遍历扩展数组,
++i
只需遍历一个单元格,如果满足条件,则另外跳过三个对角线 (3xA)i += 3
。(++i + 1)%(size+1)?:(i += 3)
-- 在(++i + 1)
我增加 i 以转到下一个单元格。然后我将它增加 1,以便索引变得尽可能多size+1
。然后是诀窍?:
,即 如果增加1的单元格个数是 的倍数size+1
,则除法的余数为0。条件中的0为假,所以后面的部分将在三元运算符中执行:
,如果有另一个数字other比零,即 是的,那么之后?
和之前的部分将被执行:
,但是那里什么都没有,所以那里什么也不会发生。在循环体中,我们简单地获取元素并检查它是否不为零。
是的,代码没有以您想要的方式使用指针。为此我深表歉意。
编码:
PS如果我的逻辑错误,请纠正我!
带有指针传递、矩阵复制位置的代码:
此外,您只检查对角线上是否有零。但是您没有检查对角线中是否没有零。
还有一点,循环条件中的比较-您需要计算要比较的内容,以免出现错误,因为 有一个非标准的增量
pointer += size + 1
。而且你还需要检查矩阵的大小是不是\u200b\u200b大于2