繁体   English   中英

如何避免在cpp中使用嵌套循环?

[英]How to avoid using nested loops in cpp?

我正在研究传感器的数字采样。 我有以下代码来计算最高幅度和相应的时间。

struct LidarPoints{
   float timeStamp;
   float Power;
}
std::vector<LidarPoints> measurement; // To store Lidar points of current measurement

在此输入图像描述

目前功率和能量是相同的(因为delta函数)并且矢量按时间的升序排列。 我想将此更改为步骤功能。 脉冲持续时间为常数10ns。

在此输入图像描述

uint32_t pulseDuration = 5;

问题是找到样本之间的任何重叠,如果有的话,加上幅度。

在此输入图像描述

我目前使用以下代码:

for(auto i= 0; i< measurement.size(); i++){
   for(auto j=i+1; i< measurement.size(); j++){
      if(measurement[j].timeStamp - measurement[i].timeStamp) < pulseDuration){
          measurement[i].Power += measurement[j].Power;
          measurement[i].timeStamp = (measurement[i].timeStamp + measurement[j].timeStamp)/2.0f;
    } 
  }
}

是否可以在没有两个for循环的情况下对此进行编码,因为我无法承受嵌套循环所花费的时间。

您可以利用矢量按timeStamp排序并使用二进制搜索找到下一个脉冲,从而将复杂度从O(n^2)O(n log n)

#include <vector>
#include <algorithm>
#include <numeric>
#include <iterator
auto it = measurement.begin();
auto end = measurement.end();

while (it != end)
{
    // next timestamp as in your code
    auto timeStampLower = it->timeStamp + pulseDuration;

    // next value in measurement with a timestamp >= timeStampLower
    auto lower_bound = std::lower_bound(it, end, timeStampLower, [](float a, const LidarPoints& b) {
            return a < b.timeStamp;
        });

    // sum over [timeStamp, timeStampLower)
    float sum = std::accumulate(it, lower_bound, 0.0f, [] (float a, const LidarPoints& b) {
            return a + b.timeStamp;
        });

    auto num = std::distance(it, lower_bound);
    // num should be >= since the vector is sorted and pulseDuration is positive
    // you should uncomment next line to catch unexpected error
    // Expects(num >= 1); // needs GSL library
    // assert(num >= 1); // or standard C if you don't want to use GSL

    // average over [timeStamp, timeStampLower)
    it->timeStamp = sum / num;

    // advance it
    it = lower_bound;
}

https://en.cppreference.com/w/cpp/algorithm/lower_bound https://en.cppreference.com/w/cpp/algorithm/accumulate

另请注意,我的算法会产生与您的算法不同的结果,因为您并没有真正计算多个值的平均值, measurement[i].timeStamp = (measurement[i].timeStamp + measurement[j].timeStamp)/2.0f

还要考虑:(我到目前为止还不是该领域的专家,所以我只是抛弃了想法,由你来决定它是否有效):用你的代码你只需“压缩”一起测量,而不是具有周期时间的测量矢量。 这可能是你打算与否。

免责声明 :未经“编译”测试。 请不要只是复制粘贴它。 它可能是不完整和不完整的。 但我希望我给你一个调查方向。

由于抖动和其他时序复杂性,您需要切换到[数值积分] [1] (例如梯形积分 ...),而不是简单求和。

如果你的值按照timeStamp的升序添加,那么if语句的else break应该不会影响结果,但应该更快。

for(auto i= 0; i< measurement.size(); i++){
   for(auto j=i+1; i< measurement.size(); j++){
      if(measurement[j].timeStamp - measurement[i].timeStamp) < pulseDuration){
          measurement[i].Power += measurement[j].Power;
          measurement[i].timeStamp = (measurement[i].timeStamp + measurement[j].timeStamp)/2.0f;
    } else {
      break;
    }
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM