如何检测超出固定范围的特定值以外的数据

时间:2014-04-16 16:20:55

标签: c

我编写了一个c程序,可以读取包含单列数据的文本文件。可以使用以下代码将所有数据读入程序:

#include <stdio.h>
#include <cstdlib>

main()
{
    char temp[20];
    float t;
    int a = 0, x = 0; //a is no. of data greater than 180 and x is no of data

    FILE *fpt;

    fpt = fopen("case i.txt", "r");

    fscanf(fpt, "%s", temp);    // read and display the column header
    printf("%s\n", temp);

    while (fscanf(fpt, "%f", &t) == 1)
    {
        printf("%.2f\n", t);
        ++x;                 //count for number of data

        if (t > 180) {
          ++a;               //count for number of data > 180
        }

        if (x > 2 && a == 2) {    //place where bug is expected to occur
          printf("2 out of 3 in a row is greater than 180");
          a=0;    //reset a back to zero
          x=0;
        }     
    }

    fclose(fpt);
    system("pause");
}

当我想要检测 2/3 数据超过180 摄氏度时,问题就出现了。我尝试了一些想法,例如何时(数据&gt; 2 )和(两个数据&gt; 180 )然后生成错误消息,但它会有bug,因为它可能有两个数据&gt; 180 但是当 4个数据被读取时,这意味着它变为 2个中的4个,而不是 2个中的3个,是吗可以编程吗?提前感谢您的帮助。

以下是示例数据和输出:

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:1)

您需要保留3个值的“滑动窗口”,表示有多少超过180个。

所以一种方法是这样的:

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

int main(void)
{
    char temp[20];
    float t;

    const int min_over = 2;
    const int max_window = 3;
    const int max_value = 180;
    char over[max_window];      // a 1 means over, 0 otherwise
    int oi = 0;
    int num_values = 0;

    FILE *fpt;

    fpt = fopen("case i.txt", "r");

    fscanf(fpt, "%s", temp);    // read and display the column header
    printf("%s\n", temp);

    memset(over, 0, max_window);

    while (fscanf(fpt, "%f", &t) == 1)
    {
        int num_hit, i;

        printf("%.2f\n", t);

        // Calculate num_hit: how many over in a window of max_window
        //
        over[oi] = (t > max_value) ? 1 : 0;

        if (++oi >= max_window)
            oi = 0;

        for ( num_hit = i = 0; i < max_window; i++ ) num_hit += over[i];

        // Only check for min_over/max_window after at least
        // max_window values read; Reset the check
        //
        if ((++num_values >= max_window) && (num_hit >= min_over))
        {
            printf("It happened!\n");
            memset(over, 0, max_window);
            num_values = 0;
        }
    }

    fclose(fpt);
    system("pause");
}

由于您希望比率为2/3,因此对应于min_over / max_window值。

我在你评论的数据样本上运行了这个:

Temperature
190.00
190.00
170.00
It happened!
200.00
190.00
100.00
It happened!
100.00
190.00
190.00
It happened!

答案 1 :(得分:1)

有大约一百万种不同的方法可以做到这一点,但你只需要跟踪有多少样本超过阈值,然后做你想做的任何事情,当你达到那个标记。

让我们说,一旦你找到你的&#34; 2中的3&#34;超过180的样本要打印列表并停止从文件中读取:

FILE *fpt;
float t;
float samples[3] = {0};             // keep a record of 3 samples
int total = 0, i;
fpt = fopen("file1.txt", "r");

while (fscanf(fpt, "%f", &t) == 1)  // read until there are no more samples
{
    total = 0;   // clear our counter
    samples[2] = samples[1];   // toss out the old 3rd sample
    samples[1] = samples[0];   // and shift them to make room for the
    samples[0] = t;            // one we just read

    for(i = 0; i<3; i++)
        if(samples[i] > 180)        // if any are over 180
            total++;                // increment our counter
    if(total == 2) {                // if 2 of the 3 are over 180, we got 2 out of 3
        printf("2 out of 3 samples are greater than 180!\n");
        printf("1: %f\n2: %f\n3:%f\n", samples[2],samples[1],samples[0]);
        break;
    }
}

fclose(fpt);

效率不高......但应该很容易理解。