欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
趣味數學(xué)和C

引子

有些人認為自己已經(jīng)厭倦了數學(xué),因為人們需要靈活的大腦才能領(lǐng)會(huì )一些數學(xué)問(wèn)題。但對于每個(gè)人來(lái)說(shuō),并不是數學(xué)的每個(gè)領(lǐng)域都是那么麻煩和令人厭倦的,即使對數學(xué)基礎不好的人也是如此。數學(xué)的其中一個(gè)領(lǐng)域――數論,對數學(xué)學(xué)的不多的普通人來(lái)說(shuō),也許會(huì )有很大的吸引力。

數論是研究整數性質(zhì)的一個(gè)學(xué)科,這也許是數學(xué)中的最古老的學(xué)科,它被具有“數學(xué)王子”之稱(chēng)的數學(xué)家高斯稱(chēng)為“數學(xué)中的女王”,因為很多數學(xué)領(lǐng)域都是為了解決數論上的問(wèn)題而出現的。實(shí)際上,學(xué)習數論并不需要有專(zhuān)業(yè)的數學(xué)基礎。你可能會(huì )對數學(xué)的各個(gè)領(lǐng)域都比較了解,如果那樣的話(huà),你會(huì )發(fā)現數論的精彩。數論被認為是“純粹的數學(xué)”,因為在過(guò)去的日子里,人們無(wú)法將數論應用在除數學(xué)之外的其它領(lǐng)域。但是在現在的實(shí)際生活中,我們可以看到對數論的很多應用,比如密碼的編解碼、隨機數產(chǎn)生器、錯誤檢查、信息安全等領(lǐng)域,我們都可以看到數論的影子。直至今日,數論仍然是一門(mén)令人著(zhù)迷的數學(xué),因為在這個(gè)領(lǐng)域中有很多未解之迷等待著(zhù)人們的解決?;蛟S,即使隨著(zhù)數學(xué)理論研究的發(fā)展和相關(guān)技術(shù)的進(jìn)步,人們也無(wú)法找到這些未解之迷的答案。

對數論的所有研究都是為了漂亮地證明各種數學(xué)問(wèn)題,或者通過(guò)已知的基本定理解決更加復雜的問(wèn)題。有意思的是,即使在數論上你未能證明一個(gè)命題是正確的,你仍然可以在實(shí)際生活中去應用它。舉個(gè)例子,大家所熟知的RSA加密算法就是基于一個(gè)假設:如果一個(gè)數是兩個(gè)以上的大素數的乘積,那么我們很難將這個(gè)大數分解。

詳細內容

現在我們要用一個(gè)簡(jiǎn)單的方法來(lái)討論數論。這是關(guān)于一個(gè)有趣的問(wèn)題――克拉茲問(wèn)題(Collatz problem)的一番討論,在這其中我們會(huì )用到很多種編程技術(shù)??死潌?wèn)題的特殊之處在于――盡管我們很容易將這個(gè)問(wèn)題講清楚,但直到今天我們仍不能保證這個(gè)問(wèn)題的算法對所有可能的輸入都管用。這個(gè)問(wèn)題也被叫做hailstone問(wèn)題、3n+1問(wèn)題、Hasse算法問(wèn)題、Kakutani算法問(wèn)題、Thwaites猜想或者Ulam問(wèn)題。這個(gè)問(wèn)題是由L. Collatz在1937年提出的。

一句話(huà),這是一個(gè)非常簡(jiǎn)單的問(wèn)題。取一個(gè)數(譯者注:嚴格地說(shuō),這個(gè)數是正整數)作為輸入,如果這個(gè)數是偶數,就將它除以2,否則就將它乘以3后再加1。(譯者注:這是一個(gè)數列計算問(wèn)題,用數學(xué)的語(yǔ)言就是,如果Xn是這個(gè)數列的第n項,而且Xn為偶數,那么這個(gè)數列的第n+1項Xn+1=(Xn)/2,如果Xn為奇數,則Xn+1=3(Xn)+1,其中n為不小于0的整數,數列的第一項X0可以取任意正整數)。這個(gè)猜想的命題是:無(wú)論你取哪一個(gè)(正整)數作為輸入,然后求這個(gè)數列后面的項,總會(huì )有某些項等于1(譯者注:確切的說(shuō)無(wú)論取哪一個(gè)正整數,總能使這個(gè)數列達成1-4-2的循環(huán),即數列中有一項等于1之后,下一項就是4,然后下一項是2,然后又是1、4、2、……。當然在本文中,作者并沒(méi)有打算討論那么多)。時(shí)至今日,仍然沒(méi)有人能證明這個(gè)命題是正確的,盡管現在通過(guò)計算機,已經(jīng)用大量的數據檢查了這個(gè)命題,所有的這些數據都通過(guò)了這個(gè)命題的測試。而這個(gè)命題的證明對人們來(lái)說(shuō)確實(shí)是一個(gè)挑戰,而如果有人能證明這個(gè)問(wèn)題,那么他無(wú)疑將會(huì )受到整個(gè)數學(xué)界的青睞。

如果將正整數n作為數列的第一個(gè)元素,那么這個(gè)數列的元素總能達到1,而數列中元素的個(gè)數就是這個(gè)數列的周期。比如你輸入5的話(huà),那么就有如下的序列:
5 16  8  4  2  1

那么這個(gè)數列的周期是6。這個(gè)序列被稱(chēng)為hailstone序列(或3n+1序列)。
用來(lái)產(chǎn)生這個(gè)數列的算法是非常簡(jiǎn)單的:

算法A (產(chǎn)生3n+1序列的算法)
A1. [輸入n]
A2. [算法結束條件] If n = 1 then exit
A3. [檢查n] If n is even then n := n / 2 else n := n * 3 + 1
A4. [得出序列中的下一個(gè)元素后] Go to A2.

很好,現在就開(kāi)始實(shí)現這個(gè)算法吧。在這里,我嘗試著(zhù)用多種編程方式來(lái)實(shí)現這個(gè)算法,以便使整個(gè)過(guò)程顯得有趣。

使用無(wú)結構編程的方法

這也許是在計算機上最基礎的編程方法了,因為不需要定義過(guò)程(譯者注:除了main之外)或是其它的什么東西。使用這種方式的問(wèn)題是,在對代碼的管理和重用方面會(huì )有所困難,因為用這種方法編出來(lái)的程序沒(méi)有抽象層,因此如果使用這種方法來(lái)進(jìn)行大規模編程會(huì )是十分困難的。

#include <iostream>
using std::cout;
using std::endl;

int main(int argc, char* argv[])
{
  int iCount = 1;
  int iNo = 22;
  int iTemp = iNo;

  while (iTemp != 1)
  {
    // 如果是偶數
    if (iTemp % 2 == 0)
    {
      iTemp /= 2;
    }
    // 如果是奇數
    else
    {
      iTemp = iTemp * 3 + 1;
    }
    ++iCount;
  }
  cout << "Cycle length of " << iNo << " is " << iCount << endl;

  return 0;
}

使用結構化編程的方法

將程序分為小的模塊(函數),會(huì )使代碼比無(wú)結構的程序代碼更易于管理和重用。在邏輯上,程序中的一個(gè)函數會(huì )完成算法中的一部分工作,但這種單元劃分可以有很強的主觀(guān)性。這種編程方法可以將問(wèn)題進(jìn)行抽象分層,以便于將一個(gè)復雜的問(wèn)題分為一些較小的部分,然后一一解決。

#include <iostream>
using std::cout;
using std::endl;

int NextTerm(int iNo)
{
  // 如果是偶數
  if (iNo % 2 == 0)
  {
    iNo /= 2;
  }
  // 如果是奇數
  else
  {
    iNo = iNo * 3 + 1;
  }

  return iNo;
}

int CalculateCycle(int iNo)
{
  int iCount = 1;

  while (iNo != 1)
  {
    iNo = NextTerm(iNo);
    ++iCount;
  }

  return iCount;
}

int main(int argc, char* argv[])
{
  const int iNo = 22;
  cout << "Cycle length  of " << iNo << " is " << CalculateCycle(iNo) << endl;

  return 0;
}

使用遞歸的方法

你知道什么是GNU嗎?GNU就是“GNU‘s Not Unix”,這不是很奇怪嗎?這個(gè)名稱(chēng)的首字母就是這個(gè)名稱(chēng)本身的縮寫(xiě),如果你將GNU這個(gè)名稱(chēng)展開(kāi),那么GNU這個(gè)詞又會(huì )出現在展開(kāi)后的名稱(chēng)中(比如:GNU‘s Not Unix ‘s Not Unix)。這只是遞歸的一個(gè)簡(jiǎn)單例子。換句話(huà)說(shuō),一個(gè)典型的定義是:遞歸是通過(guò)重復擴展自身的方法來(lái)描述一件事物的方法。對編程語(yǔ)言來(lái)說(shuō),遞歸就是一個(gè)函數調用它自己。使用遞歸的典型例子是求階乘、求Fibonacci問(wèn)題、漢諾(Hanoi)塔問(wèn)題等等。

#include <iostream>
using std::cout;
using std::endl;

int CalculateCycle(int iNo, int iCount)
{
  ++iCount;
  if (iNo == 1)
  {
    return iCount;
  }
  else
  {
    if (iNo % 2 == 0)
    {
      iNo /= 2;
      iCount = CalculateCycle(iNo, iCount);
    }
    else
    {
      iNo = iNo * 3+ 1;
      iCount = CalculateCycle(iNo, iCount);
    }
  }

  return iCount;
}

int main(int argc, char* argv[])
{
  const int iNo = 22;
  cout << "Cycle length of " << iNo << " is = "
    << CalculateCycle(iNo, 0) << endl;

  return 0;
}

使用面向對象編程的方法

面向對象編程是一種編程方法,在這種方法中,你可以建立類(lèi)并且建立這些類(lèi)的實(shí)例,我們也可以稱(chēng)這些實(shí)例為“對象”。在技術(shù)上,“類(lèi)”是在一個(gè)整體中定義變量和方法的原型。這個(gè)問(wèn)題很小,你并不能通過(guò)這個(gè)問(wèn)題看到面向對象編程所有的特點(diǎn)。下面這個(gè)程序并不是面向對象的,而是采用基于對象的技術(shù)。

#include <iostream>
using std::cout;
using std::endl;

class Collatz
{
private:
  int m_iCycle;
  int m_iNo;

  int NextTerm(int p_iNo);

public:
  Collatz(int p_iNo = 0);
  void CalculateCycle();
  int GetCycle() const;
};

Collatz::Collatz(int p_iNo) : m_iNo(p_iNo), m_iCycle(1)
{
  if (m_iNo < 1)
    throw std::out_of_range("No should be greater than 0");
}

int Collatz::NextTerm(int p_iNo)
{
  // 如果是偶數
  if (p_iNo % 2 == 0)
  {
    p_iNo /= 2;
  }
  // 如果是奇數
  else
  {
    p_iNo = p_iNo * 3 + 1;
  }

  return p_iNo;
}

void Collatz::CalculateCycle()
{
  while (m_iNo != 1)
  {
    m_iNo = NextTerm(m_iNo);
    ++m_iCycle;
  }
}

int Collatz::GetCycle() const
{
  return m_iCycle;
}

int main(int argc, char* argv[])
{
  const int iNo = 22;

  try
  {
    Collatz objCollatz(iNo);   
    objCollatz.CalculateCycle();
    cout << "Cycle length of " << iNo << " is "
      << objCollatz.GetCycle() << endl;
  }
  catch(std::out_of_range& ex)
  {
    cout << ex.what() << endl;
  }

  return 0;
}

使用泛型編程的方法

“泛型的(Generic)”就是“概括的”、“通用的”。在技術(shù)上,泛型編程的意思是,以一種方式來(lái)編寫(xiě)程序,在這種方式下編出來(lái)的程序可以對各種不同的獨立的數據類(lèi)型都能正常的運行。泛型程序應該對所有的數據類(lèi)型都提供良好的支持,并能完成程序應該完成的功能。使用C++模板是一種泛型編程的途徑。

#include <iostream>
using std::cout;
using std::endl;

template <typename T>
class Collatz
{
private:
  T m_iCycle;
  T m_iNo;

  int NextTerm(T p_iNo);

public:
  Collatz(T p_iNo = 0);
  void CalculateCycle();
  T GetCycle() const;
};

template <typename T>
Collatz<T>::Collatz(T p_iNo) : m_iNo(p_iNo), m_iCycle(1)
{
  if (m_iNo < 1)
    throw std::out_of_range("No should be greater than 0");
}

template <typename T>
int Collatz<T>::NextTerm(T p_iNo)
{
  // 如果是偶數
  if (p_iNo % 2 == 0)
  {
    p_iNo /= 2;
  }
  // 如果是奇數
  else
  {
    p_iNo = p_iNo * 3 + 1;
  }

  return p_iNo;
}
template <typename T>
void Collatz<T>::CalculateCycle()
{
  while (m_iNo != 1)
  {
    m_iNo = NextTerm(m_iNo);
    ++m_iCycle;
  }
}

template <typename T>
T Collatz<T>::GetCycle() const
{
  return m_iCycle;
}

int main(int argc, char* argv[])
{
  const int iNo = 22;

  try
  {
    Collatz<int> objCollatz(iNo);   
    objCollatz.CalculateCycle();
    cout << "Cycle length of " << iNo << " is " << objCollatz.GetCycle() << endl;
  }
  catch(std::out_of_range& ex)
  {
    cout << ex.what() << endl;
  }

  return 0;
}

使用模板元編程的方法

模板元編程(Template Meta Programming)是C++中最漂亮的編程技術(shù)。在這種方法中,你可以使用編譯器來(lái)做原本應該由程序本身完成的工作。也可以這樣說(shuō),它看起來(lái)像是根據程序來(lái)寫(xiě)程序。在模板元編程中,你可以將C++編譯器當做解釋器,比如,編譯器可以將模板展開(kāi)并生成程序運行時(shí)運行的二進(jìn)制代碼,這樣,執行編譯后程序的速度會(huì )非???,因為一些數據已經(jīng)在編譯時(shí)由編譯器計算出來(lái)。如果沒(méi)有消耗資源的話(huà)就什么都算不出來(lái),但這種方法可以消耗編譯時(shí)的資源(通過(guò)編譯器的計算能力)。編譯時(shí)耗費的時(shí)間會(huì )有所增加,這取決于使用這種方法時(shí)所用算法的特性。

#include <iostream>
using std::cout;
using std::endl;

template<int N>
class CalculateCycle
{
public:
  enum { count = CalculateCycle<N % 2 ?  (N * 3 + 1) : (N / 2) >::count + 1;};
};

template <>
class CalculateCycle<1>
{
public:
  enum { count = 1 };
};

int main(int argc, char* argv[])
{
  const int iNo = 22;
  cout << "Cycle length of " << iNo << " is = "
    << CalculateCycle<iNo>::count << endl;

  return 0;
}

譯者注:實(shí)際上,如果使用模板元編程的方法來(lái)解決問(wèn)題的話(huà),代碼往往并不能通過(guò)編譯,因為編譯器會(huì )提示編譯出錯信息,比如上面的程序在Visual C++中的編譯出錯信息是:
--------------------Configuration: tmp_1 - Win32 Debug--------------------
Compiling...
tmp_1.cpp
H:\Documents and Settings\seafrog\桌面\tmp\tmp_1.cpp(9) : error C2760: syntax error : expected ‘,‘ not ‘;‘
        H:\Documents and Settings\seafrog\桌面\tmp\tmp_1.cpp(9) : see reference to class template instantiation ‘CalculateCycle<2>‘ being compiled
        H:\Documents and Settings\seafrog\桌面\tmp\tmp_1.cpp(9) : see reference to class template instantiation ‘CalculateCycle<4>‘ being compiled
        H:\Documents and Settings\seafrog\桌面\tmp\tmp_1.cpp(9) : see reference to class template instantiation ‘CalculateCycle<8>‘ being compiled
        H:\Documents and Settings\seafrog\桌面\tmp\tmp_1.cpp(9) : see reference to class template instantiation ‘CalculateCycle<16>‘ being compiled
        H:\Documents and Settings\seafrog\桌面\tmp\tmp_1.cpp(9) : see reference to class template instantiation ‘CalculateCycle<5>‘ being compiled
        H:\Documents and Settings\seafrog\桌面\tmp\tmp_1.cpp(9) : see reference to class template instantiation ‘CalculateCycle<10>‘ being compiled
        H:\Documents and Settings\seafrog\桌面\tmp\tmp_1.cpp(9) : see reference to class template instantiation ‘CalculateCycle<20>‘ being compiled
        H:\Documents and Settings\seafrog\桌面\tmp\tmp_1.cpp(9) : see reference to class template instantiation ‘CalculateCycle<40>‘ being compiled
        H:\Documents and Settings\seafrog\桌面\tmp\tmp_1.cpp(9) : see reference to class template instantiation ‘CalculateCycle<13>‘ being compiled
        H:\Documents and Settings\seafrog\桌面\tmp\tmp_1.cpp(9) : see reference to class template instantiation ‘CalculateCycle<26>‘ being compiled
        H:\Documents and Settings\seafrog\桌面\tmp\tmp_1.cpp(9) : see reference to class template instantiation ‘CalculateCycle<52>‘ being compiled
        H:\Documents and Settings\seafrog\桌面\tmp\tmp_1.cpp(9) : see reference to class template instantiation ‘CalculateCycle<17>‘ being compiled
        H:\Documents and Settings\seafrog\桌面\tmp\tmp_1.cpp(9) : see reference to class template instantiation ‘CalculateCycle<34>‘ being compiled
        H:\Documents and Settings\seafrog\桌面\tmp\tmp_1.cpp(9) : see reference to class template instantiation ‘CalculateCycle<11>‘ being compiled
        H:\Documents and Settings\seafrog\桌面\tmp\tmp_1.cpp(23) : see reference to class template instantiation ‘CalculateCycle<22>‘ being compiled
       ……

這就是模板元編程的運行結果,我們在CalculateCycle模板后的尖括號中可以看到這個(gè)序列中的所有元素:
22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1

而且,如果你把這一句 
enum { count = CalculateCycle<N % 2 ?  (N * 3 + 1) : (N / 2) >::count + 1;};
中第一個(gè)分號(;)改為逗號(,)的話(huà),你會(huì )編譯成功,運行編譯后的可執行文件,從而得到這個(gè)序列的周期count:

Cycle length of 22 is = 16

模板元編程確實(shí)是一個(gè)漂亮的編程方法。但為什么我們可以從編譯器得到本該由我們的代碼算出的結果呢?大家可以參考《C++模板元編程》(機械工業(yè)出版社《軟件研發(fā)》2004年2月號48頁(yè),榮耀著(zhù))一文。同時(shí),模板元編程并不一定總是管用,如果你使用其他的編譯器(比如Dev-C++),在編譯出錯信息中就有可能不會(huì )顯示出運行結果。

(完,2005年8月2日稿)

 




本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
選擇排序
數值交換算法
各種排序算法C++實(shí)現(冒泡,選擇,插入,快速,歸并,堆)
今年網(wǎng)易最后一道C++筆試題是考了這樣一道題目
C++11 右值引用&&
template_sort.cpp
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久