没有参数的递归

时间:2018-08-04 05:48:08

标签: c++ recursion

我需要创建一个c ++程序,该程序使用不带参数的递归来计算多边形的面积,但将其分成较小的三角形。

我的问题是,当它不调用任何参数时,我不知道如何创建递归函数,不幸的是Google也不帮我找到任何信息。

认为我已经创建了基本案例,但不确定下一步该怎么做。

double Polygon::get_area() const{
   if ((xs.size() <3) || (ys.size() <3)) return 0;
   if ((xs.size() == 3) || (ys.size() == 3))  return ((xs[0]*ys[1] + xs[1]*ys[2] + xs[2]*ys[0]) - ys[0]*xs[1]- ys[1]*xs[2] - ys[2]*xs[0]) / 2;

};

很高兴提供进一步的代码,但是我不想要答案,我想了解如何完成任务。

任务说明: 角为(x1,y1),(x2,y2),(x3,y3)的三角形的面积为:(x1 * y2 + x2 * y3 + x3 * y1-y1 * x2- y2 * x3-y3 * x1)/ 2我们可以通过将凸多边形切成三角形来计算其面积。计算每个三角形的面积并求和,得出多边形的面积。 在polygon.cpp中将get_area()实现为递归函数。还要在polygon.cpp中实现成员函数add()。  我们得到了一个头文件:

class Polygon {
public:
void add(double x, double y); // add a vertex
double get_area() const; // a recursive function
private:
vector<double> xs; // x-coordinates of the vertices
vector<double> ys; // corresponding y-coordinates
};

TIA

2 个答案:

答案 0 :(得分:0)

因为您只是问该怎么做?,所以这里是:

  • 创建一个课程Polygon
  • Polygon具有一个数据成员作为多边形坐标数组。
  • 创建一个私有成员函数,该成员函数可对多边形坐标进行操作并返回多边形的面积
  • Polygon具有公共成员功能double get_area()。在get_area()中,调用递归函数以计算面积并返回结果。

您可以看到非递归实现working here和递归实现working here

以下是非递归实现的代码:

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

/**
Class to represent a point in plane
*/
class Point
{
    public:
    int X, Y;
    Point(int x, int y){X = x; Y = y;}
};

class Polygon
{
    //To hold the points
    vector<Point*> coordinates;

    public:
    //constructor:
    //  sides - For polygone, side = number of points
    //  points - All points of polygon as (x, y) pair
    Polygon(int sides, int points[][2])
    {
        //Add all points to the vector 'coordinates'
        while(--sides >= 0)
        {
            coordinates.push_back(new Point(points[sides][0], points[sides][1]));
        }
    }

    //Helper function to add a point at a latter time with given (x, y)
    void addPoint(int x, int y)
    {
        coordinates.push_back(new Point(x, y)); 
    }

    //Helper function to add a point at a latter time with given obect of Point
    void addPoint(Point point)
    {
        coordinates.push_back(new Point(point.X, point.Y)); 
    }

    double getArea()
    {
        double area = 0;
        int len = coordinates.size();
        //Fix the point at 0 coordinate
        Point p1 = *coordinates[0];
        while(--len >1)
        {
            //get other 2 points to create traingle
            Point p2 = *coordinates[len];
            Point p3 = *coordinates[len -1];
            area += abs((p1.X*(p2.Y - p3.Y) + p2.X*(p3.Y - p1.Y) + p3.X*(p1.Y - p2.Y))/2.0);
        }
        return area;
    }

    ~Polygon()
    {
        //Free dynamically allocated memory
        int len = coordinates.size();
        while(len--)
        {
            delete coordinates[len];
        }
    }
};


int main() {
    int sides[][2] = {{15,15}, {23,30}, {50,25}};
    Polygon p(3, sides);
    cout<<p.getArea()<<endl;
    return 0;
}

方法:要将多边形划分为三角形,请固定一个点并获取另外两个点(请参见下图)。添加所有创建的三角形的面积。

Image to visualize the approach

答案 1 :(得分:0)

从字面上理解double get_area() const是递归的要求意味着您必须必须使用成员变量来跟踪面积计算的状态。此外,由于mutable被声明为get_area,因此该成员变量将必须标记为const

在我看来,最简单的方法是存储当前正在计算面积的三角形的索引。这从1到xs.size()-2(对于N边的凸多边形,只需要N-2个非零面积的三角形即可得到其面积)。您不需要将中间区域存储在任何地方,因为return语句的形式为return (area of current triangle) + get_area();

显然,get_area将需要增加当前三角形的(可变)索引。当您到达最后一个三角形时,需要将索引重置为1,以便下次调用它时将重新开始。您还必须通过使用一个单独的return语句(不调用get_area并仅返回最终三角形的面积)来停止递归。

当然,正如其他人指出的那样,这不是解决此问题的最自然方法,因此循环会更有意义。我不确定您的指导老师是否已经认真措辞了该要求,以迫使您考虑如何解决这一特殊的技术难题,或者该要求实际上没有看起来那么严格。例如,也许您刚刚被教过mutable,这是一项测试,旨在了解您是否记得所教的内容。很高兴知道您如何进行此操作以及您的老师的意图是什么。


编辑

您的评论表明,这里的目的是递归地将多边形减少一个顶点,因此其思想是让get_area返回涉及前三个顶点的三角形的面积,然后创建另一个“多边形”对象省略了第一个三角形,并在其上调用了get_area。因此,get_area的递归不在同一个Polygon实例中,而是在一系列实例中。用伪代码:

Polygon::get_area() const
{
  if ( polygon is a point or line )
  {
    return 0;
  }
  else if ( polygon is a triangle )
  {
    return area of triangle;
  }
  else
  {
    Polygon reducedPolygon;
    Add all vertices apart from the second vertex to reducedPolygon
    return (area of triangle of first three vertices)
         + reducedPolygon.get_area();
  }

}