(под редакцией, чтобы для Moving Target.)
следующие работы на вашем (самого ограниченного!) Набора выборочных данных. Он работает следующим образом:
- Загрузите набор данных в память и сохраните его в простой структуре.
- Для каждого элемента данных столбца/столбца найдите нужные элементы: (строка, col> = 1), (строка> = 1, col) и (строка> = 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
...
(и т.д. - бежать, чтобы увидеть результаты)
Где дополнительные 'данные 'исходит, как' 150.5'? Это очень неясно. – Jotne
Уважаемый Jotne, очень ясно, что вы не знаете, что такое билинейная интерполяция, большое спасибо за негативное голосование. – user3304642
Я не дал вам отрицательного голоса, что вы должны обвинять других. – Jotne