3

我试图找到下面给出的连续 while 循环的最小值和最大值,但不知何故我无法得到正确的逻辑。请让我知道我哪里出错了。

while (true)
   {
         Function(&RawX, &RawY, &RawZ);// Keeps generating new RawX,Y and Z values

         if(MaxRawX < RawX)
            MaxRawX = RawX;
         if(MinRawX > RawX)
            MinRawX = RawX;

         Output("MaxRawX:%0.2f",MaxRawX);
   }

我使用上述算法面临的问题是 RawX、RawY 和 RawZ 的值在不断变化。例如:在某一时刻,我的值范围从 -46 到 -35。我希望我的程序将 MinRawX 显示为 -46,将 MaxRawX 显示为 -35。在其他时候,我的值可能在 201 到 215 之间,我希望它显示 MaxRawX 为 215,MinRawX 显示为 201。它基本上是我从硬件接收到的一些传感器角度数据。考虑到这是非常基本的但无法弄清楚,我确信我在这里做错了。有什么建议么?

4

3 回答 3

5

如果我理解正确,您希望在给定时间范围内拥有最小值和最大值。您使用的解决方案保持程序开始以来的最小值和最大值。

根据您的需要,您有几种解决方案:例如,您可以不时重置最小值和最大值,就像@dirkgently 建议的那样。如果您想要一个移动范围,以便在任何时间点都有n最后一次测量的最小值和最大值,那么您将不得不使用更复杂的解决方案。我唯一能想到的是将测量值保存在 FIFO 容器中:

std::deque<int> lastRawXs;
const int frameSize = 100; // only keep the last 100 measures    

while (true)
{
    // Keeps generating new RawX,Y and Z values
    Function(&RawX, &RawY, &RawZ);// 

    if (lastRawXs.size() >= frameSize)
    {
        lastRawXs.pop_front();
    }
    lastRawXs.push_back(RawX);

    typedef std::deque<int>::const_iterator iterator;
    std::pair<iterator, iterator> minMaxRawX =
        boost::minmax_element(lastRawXs.begin(), lastRawXs.end());

    Output("MinRawX:%0.2f", *minMaxRawX.first);
    Output("MaxRawX:%0.2f", *minMaxRawX.second);
}

编辑:这是使用循环缓冲区的替代(更好)解决方案:

const int frameSize = 100;
std::circular_buffer<int> lastRawXs(frameSize);

while (true)
{
    Function(&RawX, &RawY, &RawZ); // keeps generating new RawX,Y and Z values

    lastRawXs.push_back(RawX); // overwrites old measures if buffer is full

    typedef std::circular_buffer<int>::const_iterator iterator;
    std::pair<iterator, iterator> minMaxRawX =
        boost::minmax_element(lastRawXs.begin(), lastRawXs.end());

    Output("MinRawX:%0.2f", *minMaxRawX.first);
    Output("MaxRawX:%0.2f", *minMaxRawX.second);
}
于 2012-04-30T13:20:45.277 回答
2

似乎您只需要最近的最大/最小值,因此您可以执行以下操作:

const int MAX_AGE = 1000; // number of samples before min/max expires
int MinRawXAge = INT_MAX;
int MaxRawXAge = INT_MAX;

while (true)
{
    if (MinRawXAge > MAX_AGE) // test to see whether MinRawX has expired
    {
        MinRawX = INT_MAX;
        MinRawXAge = 0;
    }

    if (MaxRawXAge > MAX_AGE) // test to see whether MaxRawX has expired
    {
        MaxRawX = INT_MIN;
        MaxRawXAge = 0;
    }

    Function(&RawX, &RawY, &RawZ); // Keeps generating new RawX, Y and Z values

    if (MaxRawX < RawX) // test for new MaxRawX
    {
        MaxRawX = RawX;
        MaxRawXAge = 0;
    }
    else
    {
        MaxRawAge++;
    }

    if (MinRawX > RawX) // test for new MinRawX
    {
        MinRawX = RawX;
        MinRawXAge = 0;
    }
    else
    {
        MinRawAge++;
    }

    Output("MinRawX: %0.2f, MaxRawX: %0.2f", MinRawX, MaxRawX);
}

这会跟踪最小值和最大值的年龄(以样本为单位),当它们超过预定阈值(在上述情况下为 1000 个样本)时,它们“过期”并被更新的最小值/最大值替换。

于 2012-04-30T13:21:04.963 回答
1

好吧,您的规范可能有问题。

您的代码将连续打印当前最大值。但从您的描述看来,您实际上并不想要最大值。所以你想要什么?

在开始编写代码之前,您需要正确的规范。

于 2012-04-30T13:09:37.193 回答