求穿過平面上最多點的直線(設計思想)

2021-07-24 05:31:03 字數 3307 閱讀 7775

作者寄語:學習中總結的一些問題,難免有紕漏,歡迎**!

一.**說明

通常在面試題目在可以看到「

求穿過二維平面上最多點的直線

」,此類問題中,比較重要的是「

特殊問題怎麼轉換為常規問題

」,這正是程式設計思想的核心,下面我將沿著這個思路進行解決上述問題。

二.解決思路

首先我在這裡使用「倒推法」的思路,也就是通常所說的「

由果索因

」法進行分析上述問題,分為下面三個步奏;

第一

「定位結果」

依據題目要求,可以得知,本題需要的結果是一條

y=kx+b

的直線,限制條件是「

穿過的點最多

」,這就是需要的結果,轉到第二步;

第二:「常規化轉換」

有了上述定位的結果,我們可以依據

結果導向

的方法進行問題的常規化轉化 ;

(1)第一步轉化為「

怎麼通過若干個點得到一條直線,並讓這條直線穿過最多的點」,

由數學知識可知:

「兩點確定一條直線。」

穿過最多的點

即兩兩確定的直線在同一條直線上

;那麼,現在的問題就可以轉化為「

得到兩兩確定的直線特徵方程

」並且對直線特徵方程進行統計,重複最多的那條就是穿過點最多的那條直線;

(2)第二步轉化為「

平面上n個點最多能確定幾條直線(考慮重複點),並對確定的直線進行樣本統計,得到重複最多的那條直線

」。類似於

「握手問題」,

可知平面上n個點最多能確定n(n-1)/2條直線(注意剔除重複點),並把這些直線方程做樣本統計得出重複最多的直線方程。這又可以轉換為「求陣列中每個不同元素出現的次數」即元素樣本統計;

(3)陣列中元素樣本統計可以轉化為「陣列排序進行重複元素的統計」或借助「map容器插入進行重複元素的統計」;

通過上述的轉化我們達到了特殊問題常規化的轉換的目的,下面第三個步奏就是進行編碼前的

模組劃分設計

,這個非常重要,直接決定了你的**的可讀性和通用擴充套件性;

第三:「模組設計」

模組劃分設計我遵守的原則就是「

最小顆粒度

」的劃分原則,這種設計的好處就是有利於**的迭代開發,易於擴充套件。自頂向下逐步設計。

(1)第一層「由點確定直線方程的函式」和「統計確定的直線方程出現的次數的函式」;

(2)第二層,設計儲存點和直線方程的資料結構;

經過上面分析設計,我們就可以進行編碼了。

三.**實現

#include#include #include#include #include using namespace std;

struct pt

;struct line

return k < rhs.k;

}return bvertical < rhs.bvertical;

}bool operator == (const line&rhs) const

return k == rhs.k;

}return bvertical == rhs.bvertical;}};

//n個點集合兩兩組合產生直線

void creakline(vector&pointstruct, vector&lineslop);

//兩個點組合產生直線的基本公式

void calslope(pt pt1, pt pt2, line &lineslope);

//利用插入到map統計得出line結構體個數的統計

void inserttomap(vector&lineslop, std::map&outmap);

//得出line結構體重複次數最多的那個結構體

void fineline(std::map&outmap);

//主函式

void main()

;pt pt2;

pt pt3;

pt pt4;

pt pt5;

pt pt6;

pointset.push_back(pt1);

pointset.push_back(pt2);

pointset.push_back(pt3);

pointset.push_back(pt4);

pointset.push_back(pt5);

pointset.push_back(pt6);

vectoralllineslop;

mapoutlineslop;

creakline(pointset, alllineslop);

inserttomap(alllineslop, outlineslop);

fineline(outlineslop);

system("pause");

}void creakline(vector&pointstruct, vector&lineslop)}}

void calslope(pt pt1, pt pt2, line &lineslope)

else

}void inserttomap(vector&lineslop, std::map&outmap)

else

++vbegin;

} outmap = testmap;

}void fineline(std::map&outmap)

}bool bvertical = maxline.bvertical;

float k = maxline.k;

float b = maxline.b;

if (bvertical)

else

}}

四.思想總結

1.程式模組劃分直接決定**處理流程的簡潔度和可讀性可擴充套件性。

2.特殊問題常規化轉化是絕大部分問題的解決方法

穿過點最多的直線

題目描述 在二維平面上,有一些點,請找出經過點數最多的那條線。給定乙個點集vectorp和點集的大小n,沒有兩個點的橫座標相等的情況,請返回乙個vector,代表經過點數最多的那條直線的斜率和截距。struct point point int xx,int yy class denseline ve...

求二維平面上共線最多的點數

思想為 統計每個點的各個斜率的直線上有多少個點 c include include include include include 隨機數通用公式 a rand n 其中的a是起始值,n是整數的範圍 要取得 a,b 的隨機整數,使用 rand b a a 要取得 a,b 的隨機整數,使用 rand ...

平面上N個點,求斜率最大的那條直線通過的兩點

平面上n個點,每兩個點都確定一條直線,求出斜率最大的那條直線所通過的兩個點 斜率不存在的情況不考慮 時間效率越高越好。關於這道題,網上已經給出了解答要點 3個點a,b,c,把它們的按x座標排序。假設排序後的順序是abc,那麼有兩種情況 1.abc共線,則k ab k bc k ac 2.abc不共線...