Что выяснилось:
Реализация оказалась куда труднее, функция использующая целые числа вылетала с ошибкой на сравнении !элементов массива!, условие A[i] == B[i] && A[i] != 0 вызывает непонятную ошибку из за оператора &&, по этому была написана функция на запятых.
Само собой я каждую функцию отдельно тестировал проверяя значения и ошибок не находил...
Есть другая проблема, программа отказывается вести себя корректно если порог(threshold) ниже 0.99, чуюя это неспроста, однако если порог равен единице и используется оператор сравнения "==", то никаких проблем в поведении нет.
Третья проблема - при наличии метаинформации в программе логика её работы и моё понимание её работы растворяются в пространстве - да работает, да при абсолютных значениях верно, но в остальном превращается в дебри через которые непробраться, по этому я максимально упростил код перед тем как его выложить.
Это проявляется в том, что если убрать мету, условие становится прозрачным A -> B, а при наличии A -> ? при чём если в место вопросительного знака что то становится, оно будет там намертво закреплено, и похоже его закрепляет условие проверки порогового значения.
Очередная модификация.
#include <stdio.h>
#include <string.h>
#include <limits.h>
#define META_SIZE 2
#define FRAME_SIZE UCHAR_MAX
#define FRAMES_MAX UCHAR_MAX
enum { FALSE, TRUE };
typedef unsigned char mbt;
mbt MF[FRAMES_MAX][META_SIZE];
mbt DF[FRAMES_MAX][FRAME_SIZE];
mbt C, SC, Meta[META_SIZE];
int metacmp(mbt * M)
{
if(M[TRUE] > M[FALSE])//Лучше?
return TRUE;//Лучше.
return FALSE;
}
int calc_meta(mbt * I)//Формирует потребности
{
//Простая потребность в поддержании длинны входящих строк
if(strlen(I) > 5)//Лучше?
{
if(Meta[TRUE] < UCHAR_MAX)//Лучше.
Meta[TRUE]++;
if(Meta[FALSE] > 0)
Meta[FALSE]--;
}
else
{
if(Meta[TRUE] > 0)
Meta[TRUE]--;
if(Meta[FALSE] < UCHAR_MAX)
Meta[FALSE]++;
}
return 0;
}
//Сравнивает 2 массива игнорируя нулевые значения
float arrcmp(mbt * A, mbt * B, int size)
{
int i;
float Af, Bf, Cf, Sf;
for(i = 0, Cf = 0, Sf = 0; i < size; i++)
{
if(A[i] > 0 && B[i] > 0)
{
Af = A[i];
Bf = B[i];
if(Af < Bf)
Cf += Af / Bf;
if(Bf < Af)
Cf += Bf / Af;
if(Bf == Af)
Cf += 1;
Sf++;
}
else break;
}
return Cf / Sf;
}
//Ищет совпадения с постепенным уменьшением требования к точности
void net_work(mbt interface[FRAME_SIZE])
{
mbt i = SC, n;
calc_meta(interface);
do//Обход событий
{
if(arrcmp(DF[i], interface, FRAME_SIZE) > 0.9)//Сравнивает события
{
i++;
if(metacmp(MF[i]) == TRUE)
{
SC = i;
memcpy(interface, DF[i], FRAME_SIZE);//Выдача результата через интерфейс
break;
}
}
i++;
}
while(i != SC);
C++;
memcpy(DF[C], interface, FRAME_SIZE);//Запоминает событие
memcpy(MF[C], Meta, META_SIZE);//Запоминает мету
}
void save(void)
{
FILE * fp = fopen("brain.mb", "wb");
if(fp != NULL)
{
fwrite(MF, sizeof(mbt), FRAMES_MAX * META_SIZE, fp);
fwrite(DF, sizeof(mbt), FRAMES_MAX * FRAME_SIZE, fp);
fclose(fp);
}
}
void load(void)
{
FILE * fp = fopen("brain.mb", "rb");
if(fp != NULL)
{
fread(MF, sizeof(mbt), FRAMES_MAX * META_SIZE, fp);
fread(DF, sizeof(mbt), FRAMES_MAX * FRAME_SIZE, fp);
fclose(fp);
}
else save();
}
void init(void)
{
memset(DF, 0, FRAMES_MAX * FRAME_SIZE);
memset(MF, 0, FRAMES_MAX * META_SIZE);
memset(Meta, 0, META_SIZE);
C = 0;
SC = 0;
load();
}
int main(void)
{
char str[UCHAR_MAX];
init();
for(;
{
memset(str, 0, UCHAR_MAX);
printf("<< ");
gets(str);
net_work(str);
printf(">> %s\n", str);
save();
}
}