我正在尝试用C++列表库制作一个farey-seq程序
当我使用第一个级别时,我的程序运行得很好,但是,由于某种原因,它在使用完第一个级别后会崩溃。
我正在使用visualstudio作为编译器。我尝试了调试器模式以及资源。该程序在资源模式下不会崩溃,但是,它不会给我偶数级别的输出。此外,出于某种原因,它给了我一半的赔率输出。
我想解决这个问题,我希望它也能在配音模式下工作。
有什么建议吗?
以下是我到目前为止所做的
class RULLZ: public list<Fraction>
{
private:
list<Fraction>::iterator head,tail,buf,buf1;
public :
Farey2()
{
this->push_front( Fraction(1,1));
this->push_front( Fraction(0,1));
}
void Add(int level)
{
Fraction *tmp,*tmp2;
buf=this->first();
for(int i=0;i<level-1;i++)
{
head=this->first();
tail=this->last();
while(head!=tail)
{
tmp=new Fraction(head->num,head->den);
head++;
if(tmp->den+head->den<=level)
{
tmp2=new Fraction(tmp->num+head->num,tmp->den+head->den);
this->insert(head,*tmp2);
head--;
}
}
this->pop_back();
}
}
friend ostream& operator<<(ostream& out, RULLZ& f)
{
for(list<Fraction>::iterator it=f.first();it !=f.last();it++)
out <<*it;
return out;
}
};
class RULLZ: public list<Fraction>
在考虑您的问题之前,上面的代码就是一个问题。C++标准容器被有意地而不是设计为基类(它们都没有虚拟析构函数),因此这会导致问题。关于为什么不应该公开从标准容器派生的原因,请参阅以下内容:
- 什么时候"还好">
- 风险
- 为什么这是一个糟糕的设计决策
- 编码指南(第60页)
- 为什么继承通常不是正确的方法
您似乎希望Add
函数将下一个X
数量的分数相加(如果我正确理解您的意图)。更好的方法是使用std::stack
:
std::stack<Fraction, std::list<Fraction>> expression;
// add fractions to your stack here
Fraction Add(unsigned int count)
{
// assume count is greater than 1 (as adding 0 fractions makes no sense, and adding 1 is trivial)
Fraction result(0, 1);
for (int i = 0; i < count; ++i)
{
Fraction a = expression.top();
expression.pop();
Fraction b = expression.top();
expression.pop();
result += a + b; // assume operators + and += have been implemented for Fraction
}
expression.push(result);
return result;
}
你似乎遇到的另一个问题是逻辑问题(同样,假设我正确理解你的意图):
for(int i=0;i<level-1;i++)
如果level
是要相加的分数,并且传入2
,则此循环将只包括第一个分数。也就是说,它不会将分数0和1相加,而是只抓取分数0并返回
for(int i=0; i < level; i++)
这将获取分数0和1相加。
我不确定在哪里,但你生成序列的逻辑似乎不正确。一个更简单的方法可以在这里找到:
#include <algorithm>
#include <cstdint>
#include <iterator>
#include <iostream>
#include <vector>
struct Fraction
{
std::uint32_t Numerator;
std::uint32_t Denominator;
Fraction(std::uint32_t n, std::uint32_t d) : Numerator(n), Denominator(d) { }
};
std::ostream& operator<<(std::ostream& os, const Fraction& f)
{
os << "(" << f.Numerator << " / " << f.Denominator << ")";
return os;
}
typedef std::vector<Fraction> FareySeries;
FareySeries generate_series(std::uint32_t depth)
{
std::uint32_t a = 0;
std::uint32_t b = 1;
std::uint32_t c = 1;
std::uint32_t d = depth;
FareySeries results;
results.emplace_back(a, b);
while (c <= depth)
{
std::uint32_t k = (depth + b) / d;
std::uint32_t nc = (k * c) - a;
std::uint32_t nd = (k * d) - b;
a = c;
b = d;
c = nc;
d = nd;
results.emplace_back(a, b);
}
return results;
}
int main()
{
const std::uint32_t DEPTH = 4;
FareySeries series = generate_series(DEPTH);
std::copy(series.begin(), series.end(), std::ostream_iterator<Fraction>(std::cout, "n"));
return 0;
}