Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在一个数组中查找具有最小绝对值的元素_C++ - Fatal编程技术网

C++ 在一个数组中查找具有最小绝对值的元素

C++ 在一个数组中查找具有最小绝对值的元素,c++,C++,我试图在一个数组中找到一个元素,它的绝对值最小。例如,在数组[5.1,-2.2,8.2,-1,4,3,-5,6]中,我希望得到值-1。我使用以下代码(myarray是1D数组,未排序) for(int i=1;i STD::Abjess(代码>,因为我的理解可以推断数据类型,因为在C++中你可以使用模板等。 如果你不想用晶圆厂显然是这样的电话 float myAbs(const float val) { return (val<0) ? -val : val; } float my

我试图在一个数组中找到一个元素,它的绝对值最小。例如,在数组[5.1,-2.2,8.2,-1,4,3,-5,6]中,我希望得到值-1。我使用以下代码(myarray是1D数组,未排序)

for(int i=1;i<8;++i)
{

如果(fabsf(myarray[i])让我给出一些有帮助的想法:

float minVal = fabsf(myarray[0]);
for (int i = 1; i < 8; ++i)
{
    if(fabsf(myarray[i])<minVal) minVal = fabsf(myarray[i]);
}

myarray[0] = minVal;
使用这种方法,通过插入数字,它们已按升序排序。较小的比较器通常是std::set的一个集合,但您可以将其更改为使用与本例中不同的内容。这可能对较大的数据集有所帮助,但您提到您只有八个值要比较,因此它确实没有帮助

八个元素是一个非常小的数字,它可能与
std::array myarray
的声明一起放在堆栈中,靠近排序函数,然后再填充数据。您应该在完整的代码集上添加这些变量,并观察有什么帮助。当然,如果您声明
std::array myarray
float[8]myarray
运行时您应该会得到相同的结果

<>你可以检查的是,如果代码< FabsF真的使用浮点作为参数,并且不将变量转换为双,这会降低性能。还有代码> STD::Abjess(<)>代码>,因为我的理解可以推断数据类型,因为在C++中你可以使用模板等。 如果你不想用晶圆厂显然是这样的电话

float myAbs(const float val)
{
   return (val<0) ? -val : val;
}
float myAbs(常量float val)
{

return(val有一些城市神话,比如内联、手工展开循环以及类似的神话,它们应该可以让你的代码更快。好消息是你不必这么做,至少如果你使用-O3编译器优化的话

坏消息是,如果您已经使用了-O3,那么您无法加快此函数的速度:编译器将优化您的代码!例如,它肯定会按照一些建议对
fabsf(myarray[0])
进行缓存。使用此“重构”可以实现的唯一功能就是将bug构建到程序中,使其可读性降低

我的建议是到其他地方寻求改进:

  • 尝试减少此代码的调用次数
  • 如果这段代码是一个瓶颈,那么我的猜测是您会一次又一次地重新计算最小值(否则将值填充到数组中大约需要相同的时间),因此缓存搜索结果
  • 将成本转移到更改数组的元素上,例如使用一些奇特的数据结构(堆、优先级队列)或跟踪元素的最小值。假设您的数组只有两个元素值
    [1,2]
    ,那么最小值是
    1
    。现在如果您更改
    • 2到3,你什么都不用做
    • 2到0,您可以轻松地将最小值更新为
      0
    • 从1到3,你必须循环所有的元素,但这种情况可能并不常见

  • 你能预先存储这些值吗

    正如@Gerstrong所提到的,将数字存储在循环之外,并且只在阵列发生变化时计算它,这将给您带来提升

    调用或只能对数组进行排序,以便正确的值位于正确的位置

    std::nth_element(v.begin(), v.begin(), v.end(), [](float& lhs, float& rhs){
        return fabsf(lhs)<fabsf(rhs);
    });
    
    std::n_元素(v.begin(),v.begin(),v.end(),[](浮点和左半球,浮点和右半球){
    
    return fabsf(lhs)一个想法是以“锦标赛”的方式进行比较,而不是线性比较。换句话说,首先比较1与2,3与4,以此类推。然后取这4个元素并执行相同的操作,然后再次进行比较,直到只剩下一个元素

    这不会更改比较的数量。由于每次比较都会从运行中删除一个元素,因此无论发生什么情况,您都将有7个比较。因此,我为什么建议这样做?因为它会从代码中删除数据依赖项。现代处理器有多个管道,可以同时停用多条指令。但是,在循环中进行比较时,每个循环迭代都取决于前一个循环。在以锦标赛方式进行比较时,前四个比较是完全独立的,因此处理器可以同时进行所有比较

    除此之外,您还可以在一个简单的循环中同时计算所有晶圆厂,并将其放入一个新数组中。由于晶圆厂的计算是独立的,因此可以很容易地加快速度。您可以先进行此操作,然后进行锦标赛式的比较以获得索引。操作数应该完全相同,只是在变化调整顺序,以便编译器可以更容易地看到缺少数据依赖关系的较大块

    具有最小绝对值的数组元素

    让数组,
    A

    A = [5.1, -2.2, 8.2, -1, 4, 3, -5, 6]
    
    A
    的最小绝对值为

    double miniAbsValue = A.array().abs().minCoeff();
    int i_minimum = 0;  // to find the position of minimum absolute value
    for(int i = 0; i < 8; i++)
     {
      double ftn = evalsH(i);
      if( fabs(ftn) == miniAbsValue )
        {
          i_minimum =  i; 
        }
      }
    

    为什么不保留数组的绝对最小值,并仅在删除内容时重新计算它。添加内容时,可能需要对当前最小值进行简单比较和更新跟踪数组[0]的绝对值如果您只关心数据集中的最小/最大值,请考虑使用<代码>堆。它在<代码> O(1)<代码>中查找MI/MAX,插入<代码> O(Logn)并删除<代码> O(Logn)。
    代码已经是最优的。正如其他人所指出的,如果你想提高性能,你需要一种不同的方法(例如更好的数据结构)。@NickZuber,我不需要最小值或最大值。相反,我需要具有最小绝对值的值。例如,在[-1,2,3,4]中,我将得到-1,而不是1。出于所有实际目的,
    std::set
    不太可能更快,因为它在插入数字时必须遵循指针链,这只是在O(nlogn)操作上需要做的更多工作。这似乎给出了最小的绝对值。问题是找到具有最小ab的值
    std::nth_element(v.begin(), v.begin(), v.end(), [](float& lhs, float& rhs){
        return fabsf(lhs)<fabsf(rhs);
    });
    
    A = [5.1, -2.2, 8.2, -1, 4, 3, -5, 6]
    
    double miniAbsValue = A.array().abs().minCoeff();
    int i_minimum = 0;  // to find the position of minimum absolute value
    for(int i = 0; i < 8; i++)
     {
      double ftn = evalsH(i);
      if( fabs(ftn) == miniAbsValue )
        {
          i_minimum =  i; 
        }
      }
    
    A(i_minimum)