【上三角下三角对称矩阵】

/*上三角下三角对称矩阵
说明:
上三角矩阵是矩阵在对角线以下的元素均为0,即A ij = 0,i > j,例如:
1 2 3     4     5
0 6 7     8     9
0 0 10     11     12
0 0 0     13     14
0 0 0     0     15
下三角矩阵是矩阵在对角线以上的元素均为0,即A ij = 0,i < j,例如:
1 0 0     0     0
2 6 0     0     0
3 7 10     0     0
4 8 11     13     0
5 9 12     14  15
对称矩阵是矩阵元素对称于对角线,例如:
1 2 3     4     5
2 6 8     8     9
3 7 10     11    12
4 8 11     13  14
5 9 12     14  15
上三角或下三角矩阵也有大部份的元素不储存值(为0),我们可以将它们使用一维阵列来储存以节省储存空间,而对称矩阵因为对
称于对角线,所以可以视为上三角或下三角矩阵来储存。

解法:
假设矩阵为nxn,为了计算方便,我们让阵列索引由1开始,上三角矩阵化为一维阵列,若以列为主,其公式为:
loc = n*(i-1) - i*(i-1)/2 + j化为以行为主,其公式为:loc = j*(j-1)/2 + i

下三角矩阵化为一维阵列,若以列为主,其公式为:loc = i*(i-1)/2 + j

若以行为主,其公式为:loc = n*(j-1) - j*(j-1)/2 + i
公式的导证其实是由等差级数公式得到,您可以自行绘图并看看就可以导证出来,对于C/C++或Java等索引由0开始的语言来说,只要
将i与j各加1,求得loc之后减1即可套用以上的公式
*/

#include<stdio.h>
#include<stdlib.h>

#define N 5

int main(void){
    int arr1[N][N] = {
        {1,2,3,4,5},
        {0,6,7,8,9},
        {0,0,10,11,12},
        {0,0,0,13,14},
        {0,0,0,0,15}
    };
    int arr2[N*(1+N)/2] = {0};
    int i, j, loc = 0;

    printf("原二维矩阵: \n");
    for(i = 0; i < N; i++){
        for(j = 0; j < N; j++){
            printf("%4d", arr1[i][j]);
        }
        printf("\n");
    }

    printf("\n以列为主: ");
    for(i = 0; i < N; i++){
        for(j = 0; j < N; j++){
            if(arr1[i][j] != 0){
                arr2[loc++] = arr1[i][j];
            }
        }
    }
    for(i = 0; i < N*(1+N)/2; i++){
        printf("%d ", arr2[i]);
    }

    printf("\n输入索引(i, j): ");
    scanf("%d %d", &i, &j);
    loc = N * i - i * (i + 1) / 2 + j;
    printf("(%d, %d) = %d", i, j, arr2[loc]);
    printf("\n");

    return 0;
}

运行结果:

时间: 2024-08-16 17:02:57

【上三角下三角对称矩阵】的相关文章

java语言打印上三角和下三角,进一步得到九九乘法表

关于下面两种图形的打印问题 ***** 与 * ****  ** *** *** ** **** *  ***** 一:程序 1.先打印下三角 2.结果 3.后打印上三角 4.结果 二:知识点 1.for的双循环 2.规律 尖朝上,可以改变条件.让条件随着外循环变化. 尖朝下,可以初始化值,让初始化随着外循环变化. 三:运用(九九乘法表) 1.程序 2.结果

python 矩阵分成上三角下三角和对角三个矩阵

diagonal Return specified diagonals. diagflat Create a 2-D array with the flattened input as a diagonal. trace Sum along diagonals. triu Upper triangle of an array. tril Lower triangle of an array. 先讲一个方阵的对角线下的下三角阵和对角线上的上三角阵提取出来(如果只需要上下三角阵,则去掉tril/tr

在excel表格里,为所有数字添上绿色小三角

在excel表格里,为所有数字添上绿色小三角的方法有4种: 1. 为一个单元格添加:直接在单元格里添加一个英文的逗号 2. 为一列数据添加:选中要添加绿色小三角的列,选择 数据-->分列-->固定宽度-->下一步-->下一步-->文本-->完成 3.为所有数据添加: 3.1 选中所有要添加绿色小三角的数据,右键-->设置单元格格式-->文本-->确定 3.2 选中所有要添加绿色小三角的数据并剪切 3.3 选择开始-->剪贴板-->鼠标移动到

OJ刷题之《矩阵下三角元素之和》

题目描述 输入一个正整数n(1<=n<=10),再输入n*n的矩阵,要求求该矩阵的下三角元素之和. 输入 输入包括n+1行第一行为整数:n 接下来的n行为矩阵数据 输出 矩阵的下三角元素之和 样例输入 5 1 2 3 4 5 2 3 4 5 6 3 4 5 6 7 4 5 6 7 8 5 6 7 8 9 样例输出 75 代码如下: #include <iostream> using namespace std; int main() { int i,j,a[10][10],n,su

从上往下打印二叉树——23

从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印.例如如下二叉树打印出的结果为1.2.3.4.5.6.7.8.9. 上面所说的也就是二叉树的层序遍历,对于层序遍历来说,首先访问的肯定是根节点,然后是其左右结点,之后就是左子树的左右结点和右子树的左右结点,依次往下,如果使用像前中后序遍历那样按照左右结点去递归打印的话肯定是不行的,因为并不能一直先访问某个左结点或者右结点,而是应该左右交叉访问: 上面的二叉树中,打印的顺序是1.2.3.4.5.6.7.8.9,可以想到按照队列的方式

从上往下打印二叉树

题目描述 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 1 /* 2 struct TreeNode { 3 int val; 4 struct TreeNode *left; 5 struct TreeNode *right; 6 TreeNode(int x) : 7 val(x), left(NULL), right(NULL) { 8 } 9 };*/ 10 class Solution { 11 public: 12 vector<int> PrintFromTopToBo

从上往下打印二叉树(分层遍历)

从上往下打印二叉树的每个节点,同一层的节点按照从左到右的顺序打印. 从上到下打印二叉树的规律:每一次打印一个节点的时候,如果该节点有子节点,则把该节点的子节点放到一个队列的末尾.接下来到队列的头部取出最早进入队列的节点,重复前面的打印操作,直到队列中所有的节点都被打印出来为止. struct TreeNode { int val; TreeNode* left; TreeNode* right; }; void LevelOrder(BinaryTreeNode* root) { if (roo

剑指Offer面试题23(Java版):从上往下打印二叉树

题目:从上往下打印二叉树的每个结点,同一层的结点按照从左到右的顺序打印.例如输入下图的二叉树,则一次打印出8,6,10,5,7,9,11. 这道题实质上考察的就是树的遍历算法,只是这种遍历不是我们熟悉的前序.中序或者后序遍历.由于我们不太熟悉这种按层遍历的方法,可能已下载也想不清楚遍历的过程. 因为按层打印的顺序决定应该先打印的根节点,所以我们从树的根节点开始分析.为了接下来能够打印8的结点的两个子节点,我们应该在遍历到该结点时把值为6和10的两个结点保存到一个容器中,现在容器内就有两个结点了.

剑指OFFER之从上往下打印二叉树(九度OJ1523)

题目描述: 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一行一个整数n(1<=n<=1000, :n代表将要输入的二叉树元素的个数(节点从1开始编号).接下来一行有n个数字,代表第i个二叉树节点的元素的值.接下来有n行,每行有一个字母Ci.Ci='d'表示第i个节点有两子孩子,紧接着是左孩子编号和右孩子编号.Ci='l'表示第i个节点有一个左孩子,紧接着是左孩子的编号.Ci='r'表示第i个节点有一个右孩