我有一个结构向量,其中包含以下类型的变量:
Date Time Low
11/1/17 929 74.25
11/1/17 930 73
11/1/17 931 75
11/1/17 932 70
等
我现在想向我的向量添加另一个名为“ LowRun”的结构,其中,LowRun是迭代中每个点的最小低点,如下所示:
Date Time Low LowRun
11/1/17 929 74.25 74.25
11/1/17 930 73 73
11/1/17 931 75 73
11/1/17 932 70 70
这是我到目前为止已经尝试过的方法,但这没有给出正确的输出:
edited:
int CalcLow_SoFar(std::vector<PriceInfo>& p)
double running_low = p[0].Low;
for (size_t i = 1; i < p.size(); ++i)
{
if (p[i].Time > 929
&& p[i].Time < 1601
&& p[i].Date == p[i - 1].Date)
{
if (p[i].Low < running_low)
{
running_low = p[i].Low;
p[i].LowRun = running_low;
}
}
}
return 0;
}
您能帮我解开吗,谢谢!
答案 0 :(得分:1)
您的代码中有几个奇怪的逻辑问题,所以我只在这里列出它们。
if (p[i].Low < p[i-1].Low)
。只要当前值小于先前值,就将running_low
分配给当前值。但是,该值很有可能在不低于最低值的情况下减小。例如,如果您有序列1, 3, 2
,则索引2的LowRun
值将分配给2,因为2小于3,即使最低值应为1。if (p[i+1].Low < running_low)
上加1,那么我正在谈论的(i
)之后的if语句将是很好的。现在不是从1到p.size()
-1,而是从2到p.size()
,因此您可以访问向量末尾的一个元素,这是未定义的行为。LowRun
值更改时才分配running_low
值。这意味着,如果某个值没有改变运行低位,则LowRun
值将被初始化,这就是垃圾值的来源。running_low
初始化为第一个元素。running_low
初始化为第一个元素的值,而是将其初始化为类似std::numeric_limits<double>::max()
的东西,这样可以确保在第一个有效条目上进行更新并将您的循环更改为从0开始。这不会影响功能,但是与main()
不同的是,您定义的其他函数根本不必返回int甚至任何东西。如果您不需要该函数返回任何内容,请使用void
。
最后,您应该养成使用包括适当缩进在内的良好格式的习惯,以免混淆自己。
固定代码:
void CalcLow_SoFar(std::vector<PriceInfo>& p)
{
double running_low = p[0].Low;
p[0].LowRun = p[0].Low;
for (size_t i = 1; i < p.size(); ++i)
{
if (p[i].Low < running_low)
{
running_low = p[i].Low;
}
p[i].LowRun = running_low;
}
}
带有日期和时间检查的版本:
void CalcLow_SoFar(std::vector<PriceInfo>& p)
{
double running_low = std::numeric_limits<double>::max();
for (size_t i = 0; i < p.size(); ++i)
{
if (p[i].Time > 929
&& p[i].Time < 1601
&& i != 0
&& p[i].Date == p[i - 1].Date
&& p[i].Low < running_low)
{
running_low = p[i].Low;
}
p[i].LowRun = running_low;
}
}
请注意,对于此版本,前几个元素的Low
值将是一个非常大的值,因为尚未遇到有效的条目,并且running_low
仍保留了我们将其初始化为的值
这里是仅包含当天低点当天值的版本,并且会忽略时间不在[930,1600]中的任何值:
void CalcLow_SoFar(std::vector<PriceInfo>& p)
{
double running_low;
for (size_t i = 0; i < p.size(); ++i)
{
if (i == 0 || p[i].Date != p[i - 1].Date)
{
running_low = std::numeric_limits<double>::max();
}
if (p[i].Time >= 930
&& p[i].Time <= 1600
&& p[i].Low < running_low)
{
running_low = p[i].Low;
}
p[i].LowRun = running_low;
}
}
类似于此答案中的第二个版本,如果当天尚未达到时间限制内的值,则LowRun
的值可能为std::numeric_limits<double>::max()
。