理解c++面向對象程序設計中的抽象理論
發表于:2007-07-04來源:作者:點擊數:
標簽:
以下是利用結構體的方法解決josephus問題: 當我們學過結構體后,我們了解到結構體自身的成員指針可以指向自身對象的地址的時候,我們很容易想到解決這個數學問題,用結構體來描述是再合適不過的了,用它可以很完美的描述環形鏈表。 代碼如下: #include iostr
以下是利用結構體的方法解決josephus問題:
當我們學過結構體后,我們了解到結構體自身的成員指針可以指向自身對象的地址的時候,我們很容易想到解決這個數學問題,用結構體來描述是再合適不過的了,用它可以很完美的描述環形鏈表。
代碼如下:
#include <
iostream>
#include <string>
using namespace s
td;
struct Children
{
int number;
Children *next;
};
void show(Children *point,int num)//環鏈輸出函數
{
for(int i=1;i<=num;i++)
{
cout<<point->number<<",";
point = point->next;
}
}
void main()
{
int num;//孩子總數
int interval;//抽選號碼
cout<<"請輸入孩子總數:";
cin>>num;
cout<<"請輸入抽選號碼:";
cin>>interval;
Children *josephus = new Children[num];//設置圈的起點指針,并動態開辟堆空間用于存儲數據
Children *point = josephus;//用于初化鏈表的指針,起始地址與josephus指針相同
for(int i=1;i<=num;i++)
{
point -> number = i;
point -> next = josephus + i % num;//利用+1取模的方式設置節點的next指針,當到最后的時候自動指向到第一個,形成環鏈
point = point->next;//將位置移到下一餓節點也就是下一個小孩的位置
}
show(point,num);
Children *cut_point;
point=&josephus[num-1];//把起始指針設置在最后一個節點,當進入循環的時候就會從0開始,這樣就好讓不需要的節點脫離
int k=0;//故意設置一個k觀察while循環了多少次
while(point->next!=point)//通過循環不斷的尋找需要放棄的節點
{
k++;
for(int i = 0;i<interval;i++)//找需要放棄的節點位置
{
cut_point=point;//存儲截斷位置指針
point=cut_point->next;//將point的指針移動到放棄的節點位置,此處也和while循環終止條件有關系
}
cut_point->next=point->next;//將截斷出的next指針設置成放棄處節點的next指針,使放棄處節點也就是不需要的節點脫離
cout<<"k:"<<k<<endl;
}
cout<<"\n最后的贏家:"<<endl<<point->number<<endl<<point<<endl<<point->next<<endl;
delete[] josephus;
cin.get();
cin.get();
}
此代碼較為難以理解的部分就是while循環的終止條件的設置,如果讀者沒有能夠理解好這部分注意看下面的圖式幫助學習。
結構體的解法非常重要,對于我們全面理解面向對象的程序設計的抽象問題是基礎,必須看明白我們才能夠進行后面知識的學習,務必認真對待。
這段代碼比較前一個程序,可讀性上有所加強,但仍然不太容易理解!

為了更容易學習便于理解,我們的圖例是以有兩個小孩圍成一圈,并且設置報數的數為1的情況來制作的。
上面的兩種解決Josephus問題的解決辦法從代碼上來看,都屬于一桿子到底的解法,第二種從結構表達上優于第一種,但是這兩個都屬于純粹的過程式程序設計,程序雖然簡短,但很難讓人看懂,程序的可讀性不高,在我們沒有學習面向對象的編程之前,聰明的人可能會把各各步驟分解出來做成由幾個函數來解決問題。
思路大致可以分為以下六個部分:
1.建立結構
2.初始化小孩總數,和數小孩的數
3.初始化鏈表并構成環鏈
4.開始通過循環數小孩獲得得勝者
5.輸出得勝者
6.返回堆內存空間
從表上看這個程序為了便于閱讀可以寫成六個函數來分別處理這六個過程,的確,這么修改過后程序的可讀性是提高了一大步,但是有缺點仍然存在,程序完全暴露在外,任何人都可以修改程序,程序中的一些程序作者不希望使用者能夠修改的對象暴露在外,各對象得不到任何的保護,不能保證程序在運行中不被意外修改,對于使用者來說還是需要具備解決Josephus問題算法的能力,一旦程序變的越來越很,,每一個參與開發的程序員都需要通讀程序的所有部分,程序完全不具備黑盒效應,給多人的協作開發帶來了很大的麻煩,幾乎每個人都做了同樣的重復勞動,這種為了解決一個分枝小問題寫一個函數,最后由很多個解決局部問題的函數組合成的程序我們叫做結構化程序設計,結構化編程較過程化編程相比可讀性是提高了,但程序不能輕易的被分割解決一個個大問題的模塊,在主函數中使用他們的時候總是這個函數調用到那個函數,如果你并不是這些函數的作者就很難正確方便的使用這些函數,而且程序的變量重名問題帶來的困擾也是很讓人頭痛的。。。。。。。
那么面向對象的程序設計又是如何解決這些問題的呢?
面向對象的程序設計的思路是這樣的:
程序 = 對象 + 對象 +對象..........
這么組合而來的
對于上面的josephus問題可以把問題分割成如下的方法進行設計(如下圖所示)

本新聞共2頁,當前在第1頁 1 2
原文轉自:http://www.kjueaiud.com