我有以列为主要方式存储的对称矩阵。但我只存储矩阵的下半部分以节省空间。
所以我的矩阵看起来像这样:
1
2 6
3 7 10
4 8 11 13
5 9 12 14 15
我必须根据该矩阵的索引i(行),j(col)编写代码来查找此矩阵中元素的位置。
我写的是这样的:
pos =(n * j) - j * j / 2 +(i - j);
pos - 我的元素在矩阵中的位置 - a [pos] n - 矩阵的大小
不幸的是,总是找不到好的位置。 我编写程序来测试它并打印出来:
1
2 6
3 7 11
4 8 12 14
5 9 13 15 17
6 10 14 16 18 18
我知道它就是这样发生的,因为当我们划分j * j / 2时,我们得到int / int。但我不知道该怎么做才能使它正常工作。
请帮忙!
答案 0 :(得分:3)
让我们一次检查一列的计算,假设:
i <= j
1 <= i <= n
1 <= j <= n:
然后:
i=1, pos=j
i=2, pos=n+j-1
i=3, pos=n+n-1+j-2
i=4, pos=n+n-1+n-2+j-3
etc...
我们可以从中推导出一个通用公式:
p=n*(i-1)+j-(i-1)*i/2
可以使用简单的C#进行测试:
using System;
using System.IO;
namespace Stream
{
class Program
{
static void Main (string [] args)
{
for (int j = 1 ; j <= 5 ; ++j)
{
for (int i = 1 ; i <= 5 ; ++i)
{
Console.Write (GetIndex (i, j).ToString ("00 "));
}
Console.WriteLine ("");
}
}
static int GetIndex (int in_i, int in_j)
{
int
n = 5,
i = Math.Min (in_i, in_j),
j = Math.Max (in_i, in_j);
return n * (i - 1) + j - (i - 1) * i / 2;
}
}
}
答案 1 :(得分:0)
首先,逐行存储矩阵(数组开头的第一行)计算索引要简单得多。
您的公式似乎有误,我会说(对于j&gt; 0):
n + (n-1) + ... + (n-j+1) + (i - j)
= (( sum [0 <= k <= j-1] (n-j+1) + k )) + (i - j)
= (n-j+1) * j + (( sum [0 <= k <= j-1] k )) + (i - j)
= (n-j+1) * j + (j * (j+1)) / 2 + (i - j)
如果你的索引(i,j)从0开始,你将第一列(有n个元素)存储在数组的第一个位置。
编辑:修改为从0开始的索引。
答案 2 :(得分:-1)
#include <iostream>
using namespace std;
int main()
{
int i=0,k=1,j=0;
int a[5][5];
int n=0;
for (j=0; j<5;j++)
{
for (i=n; i<5;i++)
{
a[i][j]=k++;
cout<<i<<" "<<j<<" "<<(a[i][j])<<'\n';
}
n++;
}
return 0;
}