作者iaminanl (吉尔摩)
看板C_and_CPP
标题Re: [问题] C++ 读档(.dat)>跨行计算>输出
时间Wed Jan 1 13:21:09 2020
原文恕删
--
如果看到这样的需求,
我觉得可以分成两个部分来想:
1. 把数字读进来
2. 算出rolling average
读数字的部分,如果不考虑data cleaning之类的,
我觉得基本上就是一行一行,用各种方法找到想要的栏位,
通常我应该是会用STL string搭配stringstream,
但考虑到这个档案的delimiter是空白,用ifstream就可以
找到栏位後就是看要用什麽资料结构来存,
考虑到档案长度未知,全部读进来有一些风险,
比如记忆体用量,或是buffer overflow之类常见的array/pointer问题,
我觉应该是思考怎麽样在读进一个数的时候,
就可以算出相对应的rolling average,
也就是这个资料结构跟算rolling average的演算法有关连
--
算n笔数据的rolling average有各种作法,比较核心的是「要记得最近的n笔资料」,
而且要「把最旧的那笔去掉,然後放进最新的一笔资料」,
因此使用queue是很自然的作法,利用他FIFO的特质,自动保存历史纪录,
新的资料进来的时候pop掉最前面的就好
这样的好处是不用自己维护历史纪录,反正都在queue里面;
而且不用把所有的资料都存起来,可以避免潜在的记忆体问题
但为了要得到rolling average,你要有这些历史资料的总和,
因此利用另外一个变数储存目前的总和,就可以得到平均值
而每次新的资料进来时,就更新总和就好,
毕竟queue可以很快的读取「最旧的那笔资料」,
搭配新进来的资料,就只是加加减减的问题,是constant time
因此记忆体用量是O(rolling avg的n),
速度是O(资料大小)。
--
以下为sample code:
https://ideone.com/3E7EhU
因为网路上的compiler通常没有提供local file system,
所以请自己产生.dat档,然後改掉58行的档名就好
然後目前是n = 2的rolling avg,
要改成别的n就修改第11行就好
以上
--
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 1.200.60.168 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1577856073.A.CB5.html
1F:→ mmmmei: queue是FIFO stack才是LIFO 01/01 16:32
嗯嗯打错惹,感激
※ 编辑: iaminanl (1.200.60.168 台湾), 01/01/2020 17:14:28