編程題——1~10

1、CMyString類的實現(主要是構造函數、拷貝構造函數、賦值運算符、異常安全性)

#include <string.h>
#include <stdio.h>
#include <iostream>

class CMyString
{
  public:
    CMyString( char* pData = NULL );
    CMyString( const CMyString &str );
    ~CMyString( );
    CMyString& operator=( const CMyString &str );

    void Print();
  
  private:
    char* m_pData;
};

CMyString::CMyString( char* pData )
{
  if( pData == NULL )
  {
    m_pData = new char[ 1 ];
    m_pData[ 0 ] = '\0';
  }
  
  else
  {
    int length = strlen( pData );
    m_pData = new char[ length + 1 ];
    strcpy( m_pData, pData );
  }
}

CMyString::CMyString( const CMyString &str )
{
  int length = strlen( str.m_pData );
  m_pData = new char[ length + 1 ];
  strcpy( m_pData, str.m_pData );
}

CMyString::~CMyString()
{
  delete [] m_pData;
}

/*
// 不安全類型(new失敗)
CMyString& CMyString::operator = ( const CMyString& str )
{
  if( this == &str )
    return *this;
  
  delete [] m_pData;
  m_pData = NULL;
  
  m_pData = new char[ strlen( str.m_pData ) + 1 ];
  strcpy( m_pData, str.m_pData );

  return *this;
}
*/

// 安全類型
CMyString& CMyString::operator = ( const CMyString& str )
{
  if( this == &str )
    return *this;
  else
  {
    CMyString strTemp( str );
  
    char* pTemp = strTemp.m_pData;
    strTemp.m_pData = m_pData;
    m_pData = pTemp;
  }

  return *this;
}

void CMyString::Print()
{
  printf( "%s", m_pData );
}

// 測試不一樣對象賦值
void Test1()
{
  printf( "Test1 begins:\n" );
  
  char text[] = "Hello World";

  CMyString str1( text );
  CMyString str2;

  str2 = str1;

  printf( "The expected result is: %s.\n", text );

  printf( "The actual result is:" );
  str2.Print();
  printf( ".\n" );
}

// 測試本身賦值給本身
void Test2()
{
  printf( "Test2 begins:\n" );
  
  char text[] = "Hello World";

  CMyString str1( text );

  str1 = str1;

  printf( "The expected result is: %s.\n", text );

  printf( "The actual result is:" );
  str1.Print();
  printf( ".\n" );
}

// 測試連續賦值
void Test3()
{
  printf( "Test3 begins:\n" );
  
  char text[] = "Hello World";

  CMyString str1( text );
  CMyString str2, str3;

  str3 = str2 = str1;

  printf( "The expected result is: %s.\n", text );

  printf( "The actual result is:" );
  str2.Print();
  printf( ".\n" );

  printf( "The expected result is: %s.\n", text );

  printf( "The actual result is:" );
  str3.Print();
  printf( ".\n" );
}

int main()
{
  Test1();
  Test2();
  Test3();
  
  return 0;
}

2、Singleton的實現

   一、ns3裏的實現

template <typename T>
class SimulationSingleton
{
public:
  /**
   * \returns the instance underlying this singleton.
   *
   * This instance will be automatically deleted when the
   * user calls ns3::Simulator::Destroy.
   */
  static T *Get (void);
private:
  static T **GetObject (void);
  static void DeleteObject (void);
};

template <typename T>
T *
SimulationSingleton<T>::Get (void)
{
  T ** ppobject = GetObject ();
  return *ppobject;
}

template <typename T>
T **
SimulationSingleton<T>::GetObject (void)
{
  static T *pobject = 0;
  if (pobject == 0)
    {
      pobject = new T ();
      Simulator::ScheduleDestroy (&SimulationSingleton<T>::DeleteObject);
    }
  return &pobject;
}

template <typename T>
void
SimulationSingleton<T>::DeleteObject (void)
{
  T **ppobject = GetObject ();
  delete (*ppobject);
  *ppobject = 0;
}

     實現程序以下:node

#include <iostream>

template <typename T>
class MySingleton
{
  public:
    static T *Get( void );
  private:
    static T **GetObject( void );
    static void DeleteObject( void );
};

// 得到實例
template <typename T>
T * MySingleton<T>::Get( void )
{
  T ** ppobject = GetObject();
  return *ppobject;
}

template <typename T>
T ** MySingleton<T>::GetObject( void )
{
  static T *pobject = 0;
  if( pobject == 0 )
    {
      pobject = new T ();
      // 安排在仿真結束時會自動調用DeleteObject()消除對象
    }
  return &pobject;
}

template <typename T>
void MySingleton<T>::DeleteObject( void )
{
  T **ppobject = GetObject ();
  delete ( *ppobject );
  *ppobject = 0;
}

// 測試產生的單例
void Test1()
{
  int* singleton1 = MySingleton<int>::Get();
  int* singleton2 = MySingleton<int>::Get();

  if( singleton1 == singleton2 )
    { std::cerr << "singleton1 == singleton2" << std::endl; }

  // 結束時自動調用MySingleton<int>::DeleteObject( );
}

int main()
{
  Test1();
  
  return 0;
}

    二、《C++設計新思惟》第6章

class Singleton
{
  public:
    static Singleton& Instance();
    ... operations ...
  
  private:
    Singleton();
    Singleton( const Singleton& );
    Singleton& operator=( const Singleton& );
    ~Singleton();
};

// 多線程下的「雙檢測鎖定」模式
Singleton& Singleton::Instance()
{
  if( !pInstance )
  {
    Guard myGuard( lock );
    if( !pInstance )
    {
      pInstance = new Singlenton;
    }
  }

  return *pInstance;
}

    多線程實現程序以下:ios

#include <iostream>
#include <stdio.h>
#include <pthread.h>
#include <cerrno>
#include <cstring>
#include <stdlib.h>


class UnixMutexPrivate
{
  public: 
    UnixMutexPrivate ();
    ~UnixMutexPrivate ();
	
    void Lock (void);
    void Unlock (void);
  private:
    pthread_mutex_t m_mutex;
};

UnixMutexPrivate::UnixMutexPrivate()
{
  pthread_mutexattr_t attr;
  pthread_mutexattr_init( &attr );

  pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_ERRORCHECK );

  pthread_mutex_init( &m_mutex, &attr );
}

UnixMutexPrivate::~UnixMutexPrivate()
{
  pthread_mutex_destroy( &m_mutex );
}

void UnixMutexPrivate::Lock( void )
{
  int rc = pthread_mutex_lock( &m_mutex );

  if( rc != 0 ) 
    {
      std::cout << "SystemMutexPrivate::Lock()" << std::endl;
      std::cout << "pthread_mutex_lock failed: " << rc << " = \""
                << std::strerror (rc) << "\"" << std::endl;
      exit( 1 );
    }
}

void UnixMutexPrivate::Unlock( void )
{
  int rc = pthread_mutex_unlock( &m_mutex );

  if( rc != 0 ) 
    {
      std::cout << "SystemMutexPrivate::Unlock()" << std::endl;
      std::cout << "pthread_mutex_unlock failed: " << rc << " = \""
                << std::strerror (rc) << "\"" << std::endl;
      exit( 1 );
    }
}

class UnixMutex 
{
  public:
    UnixMutex();
    ~UnixMutex();

    // Acquire ownership of the Mutual Exclusion object.
    void Lock();

   // Release ownership of the Mutual Exclusion object.
   void Unlock();
	
 private:
   UnixMutexPrivate *m_priv;
};

UnixMutex::UnixMutex() 
  : m_priv( new UnixMutexPrivate () )
{
 
}

UnixMutex::~UnixMutex() 
{
 delete m_priv;
}

void UnixMutex::Lock ()
{
  m_priv->Lock ();
}

void UnixMutex::Unlock ()
{
  m_priv->Unlock ();
}

class CriticalSection
{
  public:
    CriticalSection( UnixMutex &mutex );
    ~CriticalSection();
  private:
    UnixMutex &m_mutex;
};

CriticalSection::CriticalSection( UnixMutex &mutex )
  : m_mutex( mutex )
{
  m_mutex.Lock ();
}

CriticalSection::~CriticalSection( )
{
  m_mutex.Unlock ();
}

static UnixMutex um;

class Singleton
{
  public:
    static Singleton& Instance( );
    static Singleton *pInstance;
  
  private:
    Singleton() { } 
    Singleton( const Singleton& );
    Singleton& operator=( const Singleton& );
    ~Singleton();
};

Singleton& Singleton::Instance()
{
  if( !pInstance )
  {
    CriticalSection cs( um );
    if( !pInstance )
    {
      pInstance = new Singleton;
    }
  }
    
  return *pInstance;
}



void* workThread( void* )
{
  Singleton::Instance();
  std::cout << " The thread: " << pthread_self()
            << "'s Singleton is : " << Singleton::pInstance << std::endl;
}


void Test1()
{
  pthread_t thread1_id;   // 線程號
  pthread_t thread2_id;
  pthread_t thread3_id;

  pthread_create( &thread1_id, NULL, workThread, NULL );
  pthread_create( &thread2_id, NULL, workThread, NULL );
  pthread_create( &thread3_id, NULL, workThread, NULL );

  pthread_join( thread1_id, NULL );
  pthread_join( thread2_id, NULL );
  pthread_join( thread3_id, NULL );
}

Singleton* Singleton::pInstance = NULL;

int main()
{
  Test1();
   
  return 0;
}

 

3、二維數組中的查找

  題目:在一個二維數組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞數組

增的順序排列。 請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有安全

該整數。多線程

      代碼以下:app

#include <iostream>

bool findNumber( int* matrix, int rows, int columns, int num )
{
  bool found = false;  

  if( matrix != NULL && rows > 0 && columns > 0 )
  {
    int row = 0;
    int column = columns - 1;
  
    while( row < rows && column >= 0 )
    {
      if( matrix[ row * columns + column ] == num )
      {
        found = true;
        break;
      }
      else if( matrix[ row * columns + column ] > num )
        --column;
      else
        ++row;
    }
  }
  
  else
  {
    std::cout << "matrix error!" << std::endl;
  }

  return found;
}

// 輸入空指針
void Test1()
{
  std::cout << "Test1 begin: " << std::endl;
  int **matrix = NULL;
  findNumber( ( int* )matrix, 1, 1, 2 );
}

//  1   2   8   9
//  2   4   9   12
//  4   7   10  13
//  6   8   11  15
// 要查找的數在數組中
void Test2()
{
  std::cout << "Test2 begin: " << std::endl;
  int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
  bool found = findNumber( ( int* )matrix, 4, 4, 7 );

  if( found == true )
    std::cout << "number exist " << std::endl;
  else
    std::cout << "number not exist " << std::endl;
}

//  1   2   8   9
//  2   4   9   12
//  4   7   10  13
//  6   8   11  15
// 要查找的數不在數組中
void Test3()
{
  std::cout << "Test3 begin: " << std::endl;
  int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
  bool found = findNumber( ( int* )matrix, 4, 4, 5 );

  if( found == true )
    std::cout << "number exist " << std::endl;
  else
    std::cout << "number not exist " << std::endl;
}

//  1   2   8   9
//  2   4   9   12
//  4   7   10  13
//  6   8   11  15
// 要查找的數比數組中最大的數大
void Test4()
{
  std::cout << "Test4 begin: " << std::endl;
  int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
  bool found = findNumber( ( int* )matrix, 4, 4, 111 );

  if( found == true )
    std::cout << "number exist " << std::endl;
  else
    std::cout << "number not exist " << std::endl;
}

int main()
{
  Test1();
  Test2();
  Test3();
  Test4();
  
  return 0;
}

4、替換空格

    請實現一個函數,把字符串中的每一個空格替換成「%20」。例如輸入「We are happy.」,則輸函數

出」We%20are%20happy「.測試

#include <iostream>
#include <vector>
#include <string>
#include <string.h>

void ReplaceBlank( char string[], int length )
{
  if( string == NULL || length <= 0 )
    return;
  
  int originalLength = 0;
  int numberofBlank = 0;
  
  int i = 0;
  while( string[ i ] != '\0' )
  {
    ++originalLength;  
  
    if( string[ i ] == ' ' )
      ++numberofBlank; 
  
    ++i;
  }

  int newLength = originalLength + numberofBlank * 2;
  if( newLength > length )
    return;

  int indexOfOriginal = originalLength;
  int indexOfNew = newLength;
  
  while( indexOfOriginal >= 0 && indexOfNew > indexOfOriginal )
  {
    if( string[ indexOfOriginal ] == ' ' )
    {
      string[ indexOfNew-- ] = '0';
      string[ indexOfNew-- ] = '2';
      string[ indexOfNew-- ] = '%';
    }
  
    else
    {
      string[ indexOfNew-- ] = string[ indexOfOriginal ];
    }

    --indexOfOriginal;
  }  
}

void Test1()
{
  char string[ 30 ] = "We are happy.";
  char expected[ 30 ] = "We%20are%20happy.";
  ReplaceBlank( string, 30 );
  if( strcmp(string, expected) == 0 )
    std::cout << "passed!" << std::endl;
  else
    std::cout << "failed!" << std::endl;  
}

int main()
{
  Test1();
  
  return 0;
}

5、從尾到頭打印鏈表ui

    輸入一個鏈表的頭結點,從尾到頭過來打印每個結點的值。this

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <stack>

struct ListNode
{
  int m_nValue;
  ListNode* m_pNext;
};

ListNode* CreateListNode( int value )
{
  ListNode* pNode = new ListNode();
  pNode->m_nValue = value;
  pNode->m_pNext = NULL;
  
  return pNode;
}

void ConnectListNodes( ListNode* pCurrent, ListNode* pNext )
{
  if( pCurrent == NULL )
  {
    printf( "Error to connect two nodes.\n" );
    exit( 1 );
  }
  
  pCurrent->m_pNext = pNext;
}

void PrintList( ListNode* pHead )
{
  printf( "PrintList start: \n" );
  ListNode* pNode = pHead;
  while( pNode != NULL )
  {
    printf( "%d\t", pNode->m_nValue );
    pNode = pNode->m_pNext;
  }
}

void AddToTail( ListNode* pHead, int value )
{
  ListNode* pNew = new ListNode();
  pNew->m_nValue = value;
  pNew->m_pNext = NULL;

  if( pHead == NULL )  // 如果空表,則用pNew做用第一個結點
  {
    pHead = pNew;
  }
  else                // 若不是空表,找到尾節點,並把其下一個節點設爲pNew
  {
    ListNode* pNode = pHead;   
    
    while( pNode->m_pNext != NULL )
      pNode = pNode->m_pNext;
    
    pNode->m_pNext = pNew;
  }
}

void RemoveNode( ListNode** pHead, int value )
{
  if( pHead == NULL || *pHead == NULL )  // 如果空表,直接返回
    return;

  ListNode* pToBeDeleted = NULL;
  if( ( *pHead )->m_nValue == value )  // 若刪除點是頭結點。則把頭結點賦值爲下一個結點
  {
    pToBeDeleted = *pHead;
    *pHead = ( *pHead )->m_pNext;
  }
  else                                // 若刪除點不是頭結點,則往下尋找
  {
    ListNode* pNode = *pHead;
    while( pNode->m_pNext != NULL && pNode->m_pNext->m_nValue != value )  // 不是,繼續往下尋址
      pNode = pNode->m_pNext;

    if( pNode->m_pNext != NULL && pNode->m_pNext->m_nValue == value )  // 是,找到刪除節點,賦值下一個結點
    {
      pToBeDeleted = pNode->m_pNext;
      pNode->m_pNext = pNode->m_pNext->m_pNext;
    }
  }

  if( pToBeDeleted != NULL )  // 如有刪除結點存在,則刪除
  {
    delete pToBeDeleted;
    pToBeDeleted = NULL;
  }
  
}

void PrintListReversingly_Iteratively( ListNode* pHead )
{
  std::stack<ListNode*> nodes;
  
  ListNode* pNode = pHead;
  while( pNode != NULL )
  {
    nodes.push( pNode );
    pNode = pNode->m_pNext;
  }

  while( !nodes.empty() )
  {
    pNode = nodes.top();
    printf( "%d\t", pNode->m_nValue );
    nodes.pop();
  }
}

// 測試多個結點
void Test1()
{
  printf( "\nTest1 is begin: \n" );
  
  ListNode* pNode1 = CreateListNode( 1 );
  ListNode* pNode2 = CreateListNode( 2 );
  ListNode* pNode3 = CreateListNode( 3 );
  ListNode* pNode4 = CreateListNode( 4 );
  ListNode* pNode5 = CreateListNode( 5 );

  ConnectListNodes( pNode1, pNode2 );
  ConnectListNodes( pNode2, pNode3 );
  ConnectListNodes( pNode3, pNode4 );
  ConnectListNodes( pNode4, pNode5 );

  PrintList( pNode1 );
  printf( "\nPrintReverList start: \n" );
  PrintListReversingly_Iteratively( pNode1 );

}

// 測試一個結點
void Test2()
{
  printf( "\nTest2 is begin: \n" );
  
  ListNode* pNode1 = CreateListNode( 1 );

  PrintList( pNode1 );
  printf( "\nPrintReverList start: \n" );
  PrintListReversingly_Iteratively( pNode1 );
}

// 測試鏈表頭指針爲NULL
void Test3()
{
  printf( "\nTest3 is begin: \n" );

  PrintList( NULL );
  printf( "\nPrintReverList start: \n" );
  PrintListReversingly_Iteratively( NULL );
  
}

int main()
{
  Test1(); 
  Test2();
  Test3();
  
  return 0;
}

6、重建二叉樹

  輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建該二叉樹。假設輸入的前序遍歷和中序遍

歷的結果中不含重複的數字。例如輸入前序遍歷{1, 2, 4, 7, 3, 5, 6, 8}和中序遍歷{4, 7, 2, 1, 5,

3, 8, 6},重建出二叉樹並輸出它的頭節點。

#include <iostream>
#include <stdio.h>
#include <exception>

int exception = 1;

struct BinaryTreeNode
{
  int m_nValue;
  BinaryTreeNode* m_pLeft;
  BinaryTreeNode* m_pRight;
};


void PrintTreeNode( BinaryTreeNode* pNode )
{
  if( pNode != NULL )
  {
    printf( "value of this node is: %d\n", pNode->m_nValue );

    if( pNode->m_pLeft != NULL )
      printf( "value of its left child is: %d.\n", pNode->m_pLeft->m_nValue );
    else
      printf( "left child is null.\n" );

    if( pNode->m_pRight != NULL )
      printf( "value of its right child is: %d.\n", pNode->m_pRight->m_nValue );
    else
      printf( "right child is null.\n" );
  }
  else
  {
    printf( "this node is null.\n" );
  }

  printf( "\n" );
}

void PrintTree( BinaryTreeNode* pRoot )
{
  PrintTreeNode( pRoot );

  if( pRoot != NULL )
  {
    if(pRoot->m_pLeft != NULL)
      PrintTree(pRoot->m_pLeft);

    if(pRoot->m_pRight != NULL)
      PrintTree(pRoot->m_pRight);
  }
}



BinaryTreeNode* ConstructCore( int* startPreorder, int* endPreorder, 
                              int* startInorder,  int* endInorder )
{
  int rootValue = startPreorder[ 0 ];
  BinaryTreeNode* root = new BinaryTreeNode();
  root->m_nValue = rootValue;
  root->m_pLeft = root->m_pRight = NULL;

  if( startPreorder == endPreorder )
  {
    if( startInorder == endInorder && *startPreorder == *startInorder )
      return root;
    else
      throw exception;
  }

  int* rootInorder = startInorder;
  while( rootInorder <= endInorder && *rootInorder != rootValue )
    ++rootInorder;

  if( rootInorder == endInorder && *rootInorder != rootValue )
    throw exception;
  
  int leftLength = rootInorder - startInorder;
  int* leftPreorderEnd = startPreorder + leftLength;
  if( leftLength > 0 )
  {
    root->m_pLeft = ConstructCore( startPreorder + 1, leftPreorderEnd,
                                   startInorder, rootInorder - 1 );
  }
  
  if( leftLength < endPreorder - startPreorder )
  {
    root->m_pRight = ConstructCore( leftPreorderEnd + 1, endPreorder,
                                    rootInorder + 1, endInorder );
  }
  
  return root;
}

BinaryTreeNode* Construct( int* preorder, int* inorder, int length )
{
  if( preorder == NULL || inorder == NULL || length <= 0 )
    return NULL;

  return ConstructCore( preorder, preorder + length - 1,
                        inorder, inorder + length - 1  );
}


void Test(char* testName, int* preorder, int* inorder, int length)
{
  if(testName != NULL)
    printf("%s begins:\n", testName);

  printf("The preorder sequence is: ");
  for(int i = 0; i < length; ++ i)
    printf("%d ", preorder[i]);
  printf("\n");

  printf("The inorder sequence is: ");
  for(int i = 0; i < length; ++ i)
    printf("%d ", inorder[i]);
  printf("\n");

  try
  {
    BinaryTreeNode* root = Construct(preorder, inorder, length);
    PrintTree(root);

  }
  catch(int exception)
  {
    printf("Invalid Input.\n");
  }
}


// 普通二叉樹
//              1
//           /     \
//          2       3  
//         /       / \
//        4       5   6
//         \         /
//          7       8
void Test1()
{
  printf( "Test1 begins: \n" );
  const int length = 8;
  int preorder[ length ] = {1, 2, 4, 7, 3, 5, 6, 8};
  int inorder[ length ] = {4, 7, 2, 1, 5, 3, 8, 6};

  Test("Test1", preorder, inorder, length);
}

int main()
{
  Test1();
  
  return 0;
}

7、棧和隊列

  用兩個棧實現一個隊列。隊列的聲明以下,清實現它的兩個函數appendTail和deleteHead,分

別完成隊列尾部插入結點和在隊列頭部刪除結點的功能。

#include <iostream>
#include <stack>
#include <exception>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

int exception_num = 1;

template<typename T> class CQueue
{
  public:
    CQueue( void );
    ~CQueue( void );

    void appendTail( const T& node );
    T deletehead();

  private:
    stack<T> stack1;
    stack<T> stack2;
};

template<typename T>  CQueue<T>::CQueue( void )
{

}

template<typename T>  CQueue<T>::~CQueue( void )
{

}

template<typename T> void CQueue<T>::appendTail( const T& element )
{
  stack1.push( element );
}

template<typename T> T CQueue<T>::deletehead()
{
  if( stack2.size() <= 0 )
  {
    while( stack1.size() > 0 )
    {
      T& data = stack1.top();
      stack1.pop();
      stack2.push( data );
    }
  }

  if( stack2.size() == 0 )
    throw exception_num;

  T head = stack2.top();
  stack2.pop();

  return head;
}

void Test( char actual, char expected )
{
  if (actual == expected )
    printf( "Test passed.\n" );
  else
    printf( "Test failed.\n" );
}

int main()
{
  CQueue<char> queue;
  try
  {
  queue.appendTail( 'a' );
  queue.appendTail( 'b' );
  queue.appendTail( 'c' );

  char head = queue.deletehead();
  Test( head, 'a' );

  head = queue.deletehead();
  Test( head, 'b' );

  queue.appendTail( 'd' );

  head = queue.deletehead();
  Test( head, 'c' );

  queue.appendTail( 'e' );

  head = queue.deletehead();
  Test( head, 'd' );

  head = queue.deletehead();
  Test( head, 'e' );

  head = queue.deletehead();
  }
  catch( int exception_num )
  {
    printf( "queue is empty!\n" );
    exit( 1 );
  }

  return 0;
  
}

八、旋轉數組的最小數字

  把一個數組最開始的若干個元素搬到數組的末尾,咱們稱之爲數組的旋轉。輸入一個遞增排序

的數組的一個旋轉,輸出旋轉數組的最小元素。例如數組{3, 4, 5, 1, 2}爲{1, 2, 3, 4, 5}的一個旋

轉,該數組的最小值爲1.

#include <iostream>
#include <exception>

int exception_num = 1;

int MinInOrder( int data[], int index1, int index2 )
{
  int result = data[ index1 ];
  for( int i = index1 + 1; i <= index2; ++i )
  {
    if( result > data[ i ] )
      result = data[ i ];
  }

  return result;
}

int Min( int data[], int length )
{
  if( data == NULL || length <= 0 )
    throw exception_num;

  int index1= 0;
  int index2 = length - 1;
  int indexMid = index1;  //  放置
  
  while( data[ index1 ] >= data[ index2 ] )
  {
    if( index2 - index1 == 1 )
    {
      indexMid = index2;
      break;
    }
    
    indexMid = ( index1 + index2 ) / 2;

    if( data[ index1 ] == data[ index2 ] && data[ indexMid ] == data[ index1 ] )
      return MinInOrder( data, index1, index2 );    

    if( data[ indexMid ] >= data[ index1 ] )
      index1 = indexMid;
    else if( data[ indexMid ] <= data[ index2 ] )
      index2 = indexMid;
  }
  
  return data[ indexMid ];
}

// 典型輸入,單調升序的數組的一個旋轉
void Test1()
{
  std::cout << "Test1 begins: " << std::endl;
  int array[] = { 3, 4, 5, 1, 2 };

  std::cout << "The minimum number is : " << Min( array, sizeof( array ) / sizeof( int ) ) << std::endl;
}

// 有重複數字,而且重複的數字恰好的最小的數字
void Test2()
{
  std::cout << "Test2 begins: " << std::endl;
  int array[] = { 3, 4, 5, 1, 1, 2 };

  std::cout << "The minimum number is : " << Min( array, sizeof( array ) / sizeof( int ) ) << std::endl;
}

// 有重複數字,而且重複的數字恰好是第一個數字和最後一個數字
void Test3()
{
  std::cout << "Test3 begins: " << std::endl;
  int array[] = { 3, 4, 5, 1, 2, 2 };

  std::cout << "The minimum number is : " << Min( array, sizeof( array ) / sizeof( int ) ) << std::endl;
}

// 單調升序數組,旋轉0個元素,也就是單調升序數組自己
void Test4()
{
  std::cout << "Test4 begins: " << std::endl;
  int array[] = { 1, 2, 3, 4, 5 };

  std::cout << "The minimum number is : " << Min( array, sizeof( array ) / sizeof( int ) ) << std::endl;
}

// 數組中只有一個數字
void Test5()
{
  std::cout << "Test5 begins: " << std::endl;
  int array[] = { 2 };

  std::cout << "The minimum number is : " << Min( array, sizeof( array ) / sizeof( int ) ) << std::endl;
}

// 輸入NULL
void Test6()
{
  std::cout << "Test6 begins: " << std::endl;

  std::cout << "The minimum number is : " << Min( NULL, 0 ) << std::endl;
}

int main()
{
  try
  {
    Test1();
    Test2();
    Test3();
    Test4();
    Test5();
    Test6();
  }
  catch( ... )
  {
    std::cout << "Invalid parameters!" << std::endl;
  }

  return 0;
 
}

九、斐波那契數列

    寫一個函數,輸入n,求斐波那契數列(Fibonacci)的第n項。

#include <iostream>

long long Fibonacci( unsigned int n )
{
  if( n <= 0 )
    return 0;
  
  if( n == 1 )
    return 1;

  return Fibonacci( n - 1 ) + Fibonacci( n - 2 );
}

int main()
{
  std::cout << " Fibonacci( 10 ) = " << Fibonacci( 10 ) << std::endl;
}
#include <iostream>

long long Fibonacci( unsigned int n )
{
  int result[ 2 ] = { 0, 1 };
  if( n < 2 )
    return result[ n ];
 
  long long fibNMinusOne = 1;
  long long fibNMinusTwo = 0;
  long long fibN = 0;
  
  for( unsigned int i = 2; i <= n; ++i )
  {
    fibN = fibNMinusOne + fibNMinusTwo;
    
    fibNMinusTwo = fibNMinusOne;
    fibNMinusOne = fibN;
  } 

  return fibN;
}

int main()
{
  std::cout << " Fibonacci( 10 ) = " << Fibonacci( 10 ) << std::endl;
}

十、二進制中1的個數

       請實現一個函數,輸入一個整數,輸出該數二進制表示中1的個數。例如把9 表示成二進制

是1001,有2位是1.所以若是輸入9,該函數輸出2.

#include <iostream>

int NumberOf1_1( int n )
{
  int count = 0;
  unsigned int flag = 1;
  
  while( flag )
  {
    if( n & flag )
      count++;
    
    flag = flag << 1;
  }

  return count;
}

int NumberOf1_2( int n )
{
  int count = 0;
  
  while( n )
  {
    ++count;
    n = ( n - 1 ) & n;
  }
  
  return count;
}

int main()
{
  std::cout << " NumberOf1_1( 5 ) = " << NumberOf1_1( 5 ) << std::endl;
  std::cout << " NumberOf1_2( 6 ) = " << NumberOf1_1( 2 ) << std::endl;
}

相關文章
相關標籤/搜索