编写程序求过点最多的直线所对应的斜率和截距

题目: 首先第一行给你一个数字n,表示一共有n个点,第二行之后依次是点的坐标。请你输出过这些点最多的那条直线的斜率和截距。

输入示例: n 0,0 1,2 输出: 1.0000 0.0000

思路: map中以斜率和截距的键值对作为键,点出现的次数为值。通过嵌套循环依次求出两点的截距和斜率,统计其出现的次数存放在这个map中。然后遍历map寻找值最大的那个键,将这个值和它的键输出。

代码:

class StraightLine
{
          
   
    struct Point
    {
          
   
        int _x;
        int _y;
        Point(int x=0,int y=0):_x(x),_y(y){
          
   };
        /*
        使用初始化列表的好处:
        1、类中存在常量,比如const int a;或者引用类型的成员属性,它们都必须初始化之后使用,因此必须使用初始化列表的方式进行构造
        2、当前类的成员属性或者基类没有默认构造函数,所以只能使用初始化列表的方式
        3、可以提高效率,例如:如果使用赋值方式进行构造,对于成员属性会先调用其默认构造函数,如果需要赋值的话,还需要调用拷贝构造,但是使用初始化列表的话可以将拷贝构造这一次调用省去,提高效率。
        */
    }
    //将计算的斜率和截距组队
    pair<double,double> calculateSlopeAndIntercept(Point p1,Point p2)
    {
          
   
         double k=(p1.x-p2.x)/(p1.y-p2.y);//计算斜率
         double b=p1.y-p1.x*k;
         return make_pair(k,b);
    }
    //找出过点最多的直线的斜率和截距
    vector<double> getLine(vector<Point> p,int n)
    {
          
   
         //在无序Map中存放对应斜率和截距出现的次数
         unordered_map<pair<double,double>,int>map;
         for(int i=0;i<p.size()-1;++i)
         {
          
   
             for(int j=i+1;j<p.size();++j)
             {
          
   
                 ++map[calculateSlopeAndIntercept(p[i],p[j])];
             }
         }
         
         //遍历Map,找出出现次数最多的那个斜率和截距并返回
         int max=0;//最多次数
         auto tmp=map.begin();
         auto resPair=tmp;
         for(auto iter=map.begin();iter!=map.end();++iter)
         {
          
   
              if(iter->second>max)
              {
          
   
                   max=iter->second;
                   resPair=iter;
              }
         }
         
         //返回结果
         vector<double,double>res(2,0);
         res[0]=resPair->first.first;//map键的第一位表示斜率
         res[1]=resPair->first.second;//map键的第二位表示截距
         return res;
    }
}
经验分享 程序员 微信小程序 职场和发展