【问题标题】:C++:List iterators are pointing to the wrong locationC++:列表迭代器指向错误的位置
【发布时间】:2013-08-15 17:01:42
【问题描述】:

警告。问题很长。

嗨。 因此,我正在尝试编写一个程序,该程序将 xy 平面中的一系列 n 点作为输入(一个简单的多边形),以及一条线 ax + by =c,并输出该线划分的多边形列表原来的一成。

所以我定义如下:

      struct point
    {
        public:
        float x, y;
        list <point>::iterator it;//if the point is an intersection point, this points to the position in the other list in class polygon where the point is located. This value is not defined for a point which is only in list pts (see class polygon)
        bool operator <(point );
        int pair;//paired intersection points will have identical pairing values 
        int poly;//poly shows if it is part of polygon or not
        point intersection( point, point, line);//returns the point of intersection

         void output();
         };

    class polygon
    {
        public:
        int n;
        list <point> pts;//stores points of original polygon as well as intersection points
        list <point> intr;// stores intersection points
        void init_it();//initialises iterators of points present in original polygon
        void init_pair();//initialises "pair" for consecutive points as 1,1,0,0,1,1...
//This allows pairing up of consecutive points the line intersects for convenient traversal of the polygon in one direction only
        void intersects(line);//solves every relevant side of polygon with the line to get a list of relevant points
        void output();
        polygon()
        {n=0;}
    };

    class line
    {
        public:
        float a,b,c;    
        float eval(point p);
    };

在此处查看intersects()main() 函数。

void polygon::intersects(line l)
{
    list <point>::iterator i=pts.begin();
    list <point>::iterator j=i;

    while(true)
    {   
        j++;
        if (j==pts.end())
               j=pts.begin();


                       if(intersect(*i,*j,l))
           {
            point p=intersection(*i,*j,l);
            pts.insert(j,p);
            intr.push_front(p);
            i++;
            list <point>::iterator k=intr.begin();
            (*i).it=k;
            (*k).it=i;
            (*k).poly=(*i).poly=0;
        }
    i=j;
}

}   

(来自main()的片段)

while(p.n>0)//flag= new beginning, beg= current beginning
    { 
        //Initialise stuff
        while(i!=beg)   
        {


            t.pts.push_back(*i);
            if( (*i).poly==1 )//point from original polygon 
            {
            //do stuff, increment i
            }
            else if(((*i).poly)==0)
            {
                //DO something



                list <point>:: iterator j= (*i).it;
                list <point>:: iterator k1=j,k2=j;
                if( j==p.intr.begin() )
                {
                    j++;
                }
                else if(j==end)
                {
                    j--;
                }
                else
                {// Gets into an infinite loop here


                    k1--;
                    k2++;
                    if((*j).pair==(*k1).pair)
                    {

                        j--;
                    }
                    else
                    {
                        j++;
                    }
                }
                t.pts.push_back(*j);
                i=(*j).it;// This line is supposed to set i to the next iterator in the "intr" list, but it doesnt change!


            }
            else
            i++;
        }

    output.push_back(t);
    }

这里的问题在于main() 函数。当我写i=(*j).it 时,它不会返回我想要的值。迭代器似乎指向同一个点,导致无限循环。我找不到任何问题。

这是一个带有答案的示例测试用例:

测试用例:

12
0 0 0 5 5 5 5 2 2 2 2 3 4 3 4 4 1 4 1 1 5 1 5 0
1 0 3

预期答案:

4
8
0 0 0 5 3 5 3 4 1 4 1 1 3 1 3 0
4
2 2 2 3 3 3 3 2
4
3 0 3 1 5 1 5 0
8
3 2 3 3 4 3 4 4 3 4 3 5 5 5 5 2

注意:我在这里使用的 算法 似乎有效(与使用过类似算法的其他人核对过),但我在实现它时似乎犯了一些错误。

【问题讨论】:

  • 好吧,我会尝试编辑它。

标签: c++ list iterator


【解决方案1】:

您的问题有很多代码需要查看。但是,另一方面,我完全了解这个几何问题。所以我要为你提供一个解决方案:

首先,保存线和点的类(简化):

struct point_2d
{
    float x , y;

    point_2d( float _x = 0.0f , float _y = 0.0f) : x( _x ) , y( _y ) {}
};


struct line
{
    float a,b,c,d; //ax + by + c = 0

    float relative_position(const point_2d& point) { return a*point.x + b*point.y + c; }
};


using polygon = std::vector<point_2d>;

这里有一个基于STL算法的解决方案(我更喜欢这个):

std::pair<polygon,polygon> divide_polygon(const polygon& poly , const line& ln)
{
    polygon up_poly;
    polygon down_poly;

    std::partition_copy( std::begin( poly ) , std::end( poly ) , std::back_inserter( up_poly ) , std::back_inserter( down_poly ) , [](const point_2d& point) { return ln.relative_position( point ) >= 0; });

    return std::make_pair( up_poly , down_poly );
}

请注意,我关闭了对您问题的前两行(问题的抽象描述)的回答。此代码完美运行,并利用了 STL(算法、容器等)。 我不会为您提供问题的确切答案。我不会为您提供在线法官问题的解决方案。这是你的作业

【讨论】:

  • 我对这里的在线法官问题的解决方案并不感兴趣。关键是,我陷入了无限循环,我认为这是因为迭代器处理中的概念问题。
  • @MihirKulkarni 哦,您已删除问题的前两行,这是唯一真正的问题,并写了 您可以在 SO 问题中使用的最糟糕的短语“你好。尝试解决这个问题”,然后是问题描述。准备被阅读问题的每个人投反对票
  • 嗯,我认为这是一个足够简洁的描述。让我再试一次。
  • 两个std::copy_if 的另一种选择是单个std::partition_copy
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-07
  • 2012-06-18
  • 2014-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多