(已编辑以允许移动目标。)
以下适用于您的(非常有限!)样本数据集。它的工作原理是这样的:
- 将数据集加载到内存中,并以简单的结构存储。
- 对于每个行/列数据项,找到所需的下一项:(row,col>=1)、(row>=1,col) 和 (row>=1,col>=1)。未经测试(因为缺乏数据),但它应该使用最接近的值。
- 如果所有四个数据点都已知,则从左到右和从上到下进行插值。
由于您的样本数据集非常小,因此很难提出优化建议。如果连续行和列之间的距离未知(数据是随机顺序的,如您的示例所示),最好尝试将整个文件读入内存。
如果您的数据是按行预先排序的,您可以在开始时读取一行,然后在每个循环中读取下一行。此外,如果数据也按列排序,您可以跳过整个find_set 例程,并立即调用interpolate 获取后续项目。
所有printf 语句周围的绒毛是因为标准C printf 格式说明符不提供您首选的输出格式。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_ITEM 25
struct data_t {
int row;
int col;
int data;
} array[MAX_ITEM];
int n_item = 0;
// interpolate A > B
// v v
// C > D
void interpolate (int A, int B, int C, int D)
{
int i,j, deltaCol,deltaRow;
float a,b, delta_AC, delta_BD, value;
a = array[A].data;
b = array[B].data;
deltaCol = 2*(array[B].col-array[A].col);
deltaRow = 5*(array[C].row-array[A].row);
delta_AC = (array[C].data-array[A].data)/(float)deltaRow;
delta_BD = (array[D].data-array[B].data)/(float)deltaRow;
// rows
for (j=0; j<=deltaRow; j++)
{
// columns
for (i=0; i<=deltaCol; i++)
{
if (j % 5)
printf ("%.1f ", array[A].row+(j/5.0f));
else
printf ("%d ", array[A].row+j/5);
if (i % 2)
printf ("%.1f ", array[A].col+(i/2.0f));
else
printf ("%d ", array[A].col+i/2);
value = a+(b-a)*((float)i/deltaCol);
if ((int)(100*value+0.5) % 100)
printf ("%.1f\n", value);
else
printf ("%d\n", (int)(value+0.5f));
}
a += delta_AC;
b += delta_BD;
}
}
// For a start row/col A find B,C,D
// where B = A(0,>=1), C=A(>=1,0), D=A(>=1,>=1)
void interpolate_from (int A)
{
int i, B=-1, C=-1, D=-1;
for (i=0; i<n_item; i++)
{
if (i == A) continue;
if (array[A].row == array[i].row)
{
if (array[A].col < array[i].col || (B != -1 && array[i].col < array[B].col))
{
B = i;
}
} else
if (array[A].row < array[i].row)
{
if (array[A].col == array[i].col)
{
C = i;
} else
{
if (array[A].col < array[i].col || (D != -1 && array[i].col < array[D].col))
{
D = i;
}
}
}
if (B+1 && C+1 && D+1)
{
interpolate (A,B,C,D);
return;
}
}
}
int main (void)
{
int i,j,k;
FILE *f;
f = fopen ("data.txt", "r");
while (n_item < MAX_ITEM && fscanf (f, "%d %d %d", &i,&j, &k) == 3)
{
array[n_item].row = i;
array[n_item].col = j;
array[n_item].data = k;
n_item++;
}
fclose (f);
for (i=0; i<n_item; i++)
interpolate_from (i);
printf ("\n");
return 0;
}
使用修改后的数据集
20 14 91
21 14 162
21 18 95
20 18 210
输出是:
20 14 91
20 14.5 105.9
20 15 120.8
20 15.5 135.6
...
(等--运行查看结果)