English 中文(简体)
C++ STL 列表计算平均值
原标题:C++ STL List calculate average

我必须纠正一些C++/STL代码。不幸的是我很少有C++经验,也不知道STL。尽管如此,我已经完成了大部分工作,但下面的函数仍然让我感到困扰:

C ++源代码:

double MyClass::CalculateAvg(const std::list<double> &list)
{
    double avg = 0;
    std::list<int>::iterator it;
    for(it = list->begin(); it != list->end(); it++) avg += *it;
    avg /= list->size();
}

C++ 头文件:

static double CalculateAvg(const std::list<int> &list);

它最有可能是用于计算列表中的平均值,但它有很多错误。我试图在网上寻找解决方案,但我找不到任何东西。如果有人能帮我解决这个问题,我会很高兴的。

Update: Thank you for your quick replies. The accepted answer solved all my problems.

最佳回答

所以,第一个错误就在那里:

std::list<int>::iterator it;

你定义了一个整数列表的迭代器,并用它来迭代双精度浮点数列表。此外,迭代器仅可用于非常量列表。你需要一个常量操作符。你应该写:

std::list<double>::const_iterator it;

最后,你忘记了返回这个值。

编辑:我没有看到,但你将列表作为参考传递,但是将其用作指针。因此,请将所有的list->替换为list.翻译:编辑:我没有看到,但是你将列表作为参考传递,但使用它作为指针。因此,请用list.替换所有的list->

问题回答

少数事物:

  1. You don t return anything. (add return avg;)
  2. The -> operator is for pointers to objects. You have a reference to a list, so you use list.begin() and not list->begin() (same for other member functions)
  3. The iterator should be a const_iterator, not iterator.

无论如何,你应该只需要做以下的事情:

返回 std::accumulate(list.begin(), list.end(), 0.0) / list.size();

如果您的使用情况允许,可以进行list.size() == 0的可选检查。

In I'm sorry, there is no text provided to translate into Chinese. Please provide the text you would like me to translate.ition to @PierreBdR answer, you should also check that list->size() is greater than 0,

就在这里之前。

  avg /= list.size();

I'm sorry, there is no text provided to translate into Chinese. Please provide the text you would like me to translate.

 if (list.size()>0) 
    //avg code here.

或者记录下作为参数接收到的列表不应为空。

   assert(list.size()>0)

与其编辑以确保迭代器引用相同类型的列表,不如将代码编写为具有迭代器类型作为模板参数的通用算法,这样会更好。

我还指出,关于<代码>的编号:,你原来的代码,大多数答复都存在一个相当严重的效率问题:鉴于名单的典型执行情况,它们再次通过清单补充数值,然后再次计算要素数目。 在理论上,list.size(>>could在不通过这些要素反复运行的情况下,但事实上很少出现这种情况(在list:size(list:splice <>/code>,但两者并不一致)。

我会写出这样的代码:

template <class fwdit> 
typename fwdit::value_type arithmetic_mean(fwdit begin, fwdit end) { 

    typedef typename fwdit::value_type res_type;

    res_type sum = res_type();
    size_t count = 0;

    for (fwdit pos = begin; pos!= end; ++pos) { 
        sum += *pos;
        ++count;
    }
    return sum/count;
}

这是泛型的,因此当你意识到 std::list 是一个糟糕的选择,而你真正应该使用 std::vector 时,它仍将继续工作(未更改)。同样,如果你想要一些 int 的算术平均值而不是 double,它也可以处理(同样,无需更改代码)。第三,即使(如上所建议的那样),你的库的 st::list::size() 的实现恰好是线性的,这仍然只遍历一次列表,所以它很可能比(原始代码的工作版本)快两倍左右。

当然,缓存会影响这一点 - 当你平均一个小列表时,第一次遍历会将整个列表放入缓存中,因此第二次遍历通常会更快(因此消除第二次遍历不会节省太多时间)。

你传递进去一个 std::list<double>,但你却创建了一个 std::list<int> 的迭代器?而且你的原型也接受一个 std::list<int>

正如Maurits Rijk所说,你还没有返回avg。另外,它编译时出现了什么错误? (Zhèng rú Maurits Rijk suǒ shuō, nǐ hái méiyǒu huítóu avg. Lìngwài, tā biānjí shí chūxiàn le shénme cuòwù?)

由于 list 是引用而不是指针,因此您不需要 -> 解引用运算符,而只需要运算符,即 it = list.begin()等等。

此外,正如其他每个人指出的那样,列表和其迭代器的模板类型参数都需要相匹配:要么是 <int>,要么是 <double>。看起来,该函数最初是为接受 double 列表编写的。

作为自我锻炼。一旦您使其正常工作,应将其转换为for_each。长期来看,这样更容易理解。

编辑

累加器更好,因为它用于二进制数值运算。

使用更复杂的对象,您还可以使用二元运算符积累如下:

auto accObjectValueA = [](double acc, const MyObject& object){ return acc + object.getValueA(); };
double sumValueA = std::accumulate(listOfObjects.begin(), listOfObjects.end(), 0, accObjectValueA );
double averageValueA = sumValueA  / listOfObjects.size();




相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?