国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

一個有趣的算法問題:如何定義一個分數類

BearyChat / 1796人閱讀

摘要:一個來自于程序設計的經典問題。注意事項負數問題。和上一點是一樣的問題,要確定方式是屬于具體的對象,還是屬于一個類。

一個來自于C++程序設計的經典問題。如何定義一個分數類,實現分數的約分化簡,分數之間的加法、減法、乘法、除法四則運算?

1.初見

剛看到這道題的時候,第一感覺是挺簡單的啊,就是基本的面向對象,定義對應的加減乘除類就可以了啊,然而到了實現的時候才發現許多問題是說起來容易做起來難,在實現的過程中,發現了許多的注意點,以及算法。

最終得出結論:這個問題著實是考察程序員基本功的一道好題

2.整體思路

分數類設計的總體思路如下:

首先是分數的表示,這就需要利用兩個變量保存分數的分子和分母;

其次是約分和通分,由于分數四則運算中需要借助約分和通分來實現,因此必須先考慮實現這兩個算法。

加法和乘法的實現。利用約分和通分就可以輕松實現。

減法和除法的實現。是加法和乘法的逆運算。和直接轉化為加法和乘法。

3.注意事項

負數問題。這個問題十分重要,在我們的算法中,都規定分母為正數,如果出現了分母為負數的情況,就分子分母同時乘以-1,把負數運算放在分子上。

函數的副作用(side effect)。盡量不要在方法中改變原來分數的值,否則會產生副作用,導致后面的運算出錯,在代碼中會說明。

靜態方法和動態方法。和上一點是一樣的問題,要確定方式是屬于具體的對象,還是屬于一個類。

除法運算中,除數不能等于0

4.代碼實現 4.1 屬性和構造方法

構造方法中有三個細節:一是使用了參數默認值,默認不寫參數時,讓分子分母都等于1;二是在構造方法中進行了分母合法性的驗證,分母等于0時直接返回錯誤信息;三是對負值進行了處理,使分數的分母永遠為正數,方便后續運算。

/**
* 分數運算類
*/
class Fraction 
{
    //定義分子和分母
    public $fenzi;
    public $fenmu;
    
    //構造函數
    function __construct($fenzi = 1,$fenmu = 1)
    {
        if ($fenmu == 0) {
            return "分母不能為0";
        }
        if ($fenmu < 0) {
            $fenmu = -$fenmu;
            $fenzi = -$fenzi;
        }
        $this->fenzi = $fenzi;
        $this->fenmu = $fenmu;
    }
}
4.2 最大公約數和最小公倍數

為了后續的約分和通分,必須先求出最大公約數和最小公倍數。求最大公約數采用輾轉相除法,而最小公倍數由以下公式可求:

最小公倍數 = (數A * 數B)/ 最大公約數

//求最大公約數用于約分
private static function _getmax($a, $b)
{
    if($a < 0) $a = -$a;
    if($b < 0) $b = -$b;
    $tmp = $a % $b;
    while($tmp != 0) {
        $a = $b;
        $b = $tmp;
        $tmp = $a % $b;
    }
    return $b;
}

//求最小公倍數用于通分
private static function _getmin($a, $b)
{
    if($a < 0) $a = -$a;
    if($b < 0) $b = -$b;   
    $max = self::_getmax($a,$b);
    $min = intval(($a * $b) / $max);
    return $min;
}

/**
 * 約分運算,基本算法為分子分母同時除以最大公約數;
 * @return void 將對象的分子分母約分為最簡形式    
 */
public function reduction()
{
    $max = $this->_getmax($this->fenzi,$this->fenmu);
    $this->fenzi = intval($this->fenzi / $max);
    $this->fenmu = intval($this->fenmu / $max);
}

這兩個方法全部都定義為靜態私有方法,只在類內調用且不需實例化。求最大公約數和最小公倍數的算法其實還有很多種,@燼醬采用了另外一種方法,C++代碼如下:

/**
 * 求最大公約數并進行約分
 * @return void
 */
int reduction()
{
    int i,comdiv,small,max;

    if(above1;i--)
    {
        if(small%i==0 &max%i==0 )
            break;
    }

    comdiv=i; //最大公約數
    if(i!=0)
    {
        above/=i;
        below/=i;
    }
    return 0;
}

這種方法的本質就窮盡法,核心思想在于for循環當中。同樣的,也可用此法求最小公倍數。

4.3 分數加減

分數加法的算法如下:

/**
 * 加法運算,寫成靜態方法,需要傳遞兩個分數對象實例。加法的基本步驟為:
 * 1. 求兩個分母的最小公倍數;
 * 2. 利用最小公倍數進行通分,此時分母就是最小公倍數,第一個分數的分子等于原來的分子*(最小公倍數/原來的分母),第二個分數的分子同理;
 * 3. 分母不變,分子相加;
 * 4. 對結果進行約分;
 * 
 * @param  fraction $fra1 分數相加的加數1
 * @param  fraction $fra2 分數相加的加數2  
 * @return fraction  $fra 分數相加的計算結果
 */
public static function add($fra1, $fra2)
{
    $fra = new Fraction();
    $min = self::_getmin($fra1->fenmu,$fra2->fenmu);
    $fenzi_left = $fra1->fenzi * ($min / $fra1->fenmu);
    $fenzi_right = $fra2->fenzi * ($min / $fra2->fenmu);

    $fra->fenmu = $min;
    $fra->fenzi = $fenzi_left + $fenzi_right;
    $fra->reduction();
    return $fra;
}

/**
 * 減法運算,加法的逆運算,只需要將參數$fra2的分子取反,將減法運算化為加法運算
 * 
 * @param  fraction $fra1 分數相減的被減數
 * @param  fraction $fra2 分數相減的減數
 * @return fraction $fra 分數相減的計算結果
 */
public static function minus($fra1, $fra2)
{
    $fra_t = new Fraction(-$fra2->fenzi,$fra2->fenmu);
    return self::add($fra1,$fra_t);
}

在上述算法中,定義了兩個靜態方法,每個方法需要傳入兩個分數對象,之后就可以按上面的算法步驟進行加法和減法運算了。其中減法運算只需要轉換為加法即可。需要注意的是,在減法運算中,存在兩種可能的寫法:

【寫法1】

$fra2->fenzi = -$fra2->fenzi;

【寫法2】

$fra_t = new Fraction(-$fra2->fenzi,$fra2->fenmu);

其中,第一種寫法直接改變了減數分子的值,這里對減法本身的結果不會造成影響,表面上看是成立的,但其實這種寫法產生了副作用,在計算乘法時,fra2就已經不是最初的分數值了,因此我們需要new一個新的對象,如寫法2所示,這樣就不會產生副作用改變分數2的值。

4.4 分數乘除

分數乘數就比較簡單了,如下所示:

/**
 * 乘法運算,分子相乘,分母相乘之后再約分
 * 
 * @param  fraction $fra1 分數相乘的乘數1
 * @param  fraction $fra2 分數相乘的乘數2
 * @return fraction $fra 分數相乘的計算結果
 */
public static function multiply($fra1,$fra2)
{
    $fra = new Fraction();

    $fenzi = $fra1->fenzi * $fra2->fenzi;
    $fenmu = $fra1->fenmu * $fra2->fenmu;

    $fra->fenzi = $fenzi;
    $fra->fenmu = $fenmu;
    $fra->reduction();
    return $fra;
}

/**
 * 除法運算,乘法運算的逆運算,只需要將參數$fra2的分子分母調換,將除法運算化為乘法運算
 * 
 * @param  fraction $fra1 分數相除的被除數
 * @param  fraction $fra2 分數相除的除數
 * @return fraction       分數相除的計算結果
 */
public static function divide($fra1,$fra2)
{
    $fra_t = new Fraction($fra2->fenmu,$fra2->fenzi);
    $fra = self::multiply($fra1,$fra_t);
    return $fra;
}
4.5 分數的表示

最后,我們需要寫一個方法,把分數以a/b的形式打印出來。

public function display()
{
    printf("%d/%d
",$this->fenzi,$this->fenmu);
}

這樣我們的分數類的定義完了。

5. 結果展示

下面展示運行結果,先寫一個調用:

$fra1 = new Fraction(3,4);
$fra1->display();

$fra2 = new Fraction(12,20);
$fra2->reduction();
$fra2->display();

$fra3 = Fraction::add($fra1,$fra2);
$fra3->display();

$fra4 = Fraction::minus($fra1,$fra2);
$fra4->display();

$fra5 = Fraction::multiply($fra1,$fra2);
$fra5->display();

$fra6 = Fraction::divide($fra1,$fra2);
$fra6->display();

如上,fra1期望直接打印出3/4, fra2對12/20先約分再輸出,期望是3/5,fra3是計算fra1和fra2的加法,fra4為減法,fra5為乘法,fra6為除法。結果如下所示:

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/30348.html

相關文章

  • 「正經字幕」太無聊?「神經玩笑機」就可以生成逗你笑趣味字幕

    摘要:最后,我們顯示了若干張圖像中所生成的趣味字幕。圖所提出的有趣字幕生成的體系結構。我們將所提出的方法稱為神經玩笑機器,它是與預訓練模型相結合的。用戶對已發布的字幕的趣味性進行評估,并為字幕指定一至三顆星。 可以毫不夸張地說,笑是一種特殊的高階功能,且只有人類才擁有。那么,是什么引起人類的笑聲表達呢?最近,日本東京電機大學(Tokyo Denki University)和日本國家先進工業科學和技...

    lastSeries 評論0 收藏0
  • 六種GAN評估指標綜合評估實驗,邁向定量評估GAN重要一步

    摘要:本文討論了多個評估指標,并從多個方面對評估指標進行了實驗評估,包括距離分類器。鑒于定性評估的內在缺陷,恰當的定量評估指標對于的發展和更好模型的設計至關重要。鑒于評估非常有難度,評估評估指標則更加困難。 作者:Qiantong Xu、Gao Huang、Yang Yuan、Chuan Guo、Yu Sun、Felix Wu、Kilian Weinberger生成對抗網絡的評估目前仍以定性評估和...

    zorro 評論0 收藏0
  • Minimax 和 Alpha-beta 剪枝算法簡介,以及以此實現井字棋游戲(Tic-tac-t

    摘要:我們在前文中考慮的那張圖就來自這篇文章,之后我們會用剪枝算法來改進之前的解決方案。剪枝算法的實現接下來討論如何修改前面實現的算法,使其變為剪枝算法。現在我們已經有了現成的和剪枝算法,只要加上一點兒細節就能完成這個游戲了。 前段時間用 React 寫了個2048 游戲來練練手,準備用來回顧下 React 相關的各種技術,以及試驗一下新技術。在寫這個2048的過程中,我考慮是否可以在其中加...

    wemall 評論0 收藏0
  • Minimax 和 Alpha-beta 剪枝算法簡介,以及以此實現井字棋游戲(Tic-tac-t

    摘要:我們在前文中考慮的那張圖就來自這篇文章,之后我們會用剪枝算法來改進之前的解決方案。剪枝算法的實現接下來討論如何修改前面實現的算法,使其變為剪枝算法。現在我們已經有了現成的和剪枝算法,只要加上一點兒細節就能完成這個游戲了。 前段時間用 React 寫了個2048 游戲來練練手,準備用來回顧下 React 相關的各種技術,以及試驗一下新技術。在寫這個2048的過程中,我考慮是否可以在其中加...

    Eirunye 評論0 收藏0
  • 推薦系統02--協同過濾

    摘要:如果做推薦系統不知道基于物品的協同過濾,那等同于做程序員不懂得冒泡排序。基于物品的八卦基于物品的協同過濾算法誕生于年,是由亞馬遜首先提出的,并在年由其發明者發表了相應的論文。 不管你有沒有剁過手,你對看了這個商品的還看了這樣的推薦形式一定不陌生。無論是貓還是狗,或者是其他電商網站,這樣的推薦產品可以說是推薦系統的標配了。 類似的還有,如點評標記類網站的喜歡了這部電影的還喜歡了,社交媒...

    jaysun 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<