最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++實現(xiàn)一維向量旋轉算法

 更新時間:2014年08月14日 10:04:27   投稿:shichen2014  
這篇文章主要介紹了C++實現(xiàn)一維向量旋轉算法,非常實用的經典算法,需要的朋友可以參考下

在《編程珠璣》一書的第二章提到了n元一維向量旋轉算法(又稱數(shù)組循環(huán)移位算法)的五種思路,并且比較了它們在時間和空間性能上的區(qū)別和優(yōu)劣。本文將就這一算法做較為深入的分析。具體如下所示:

一、問題描述

將一個n元一維向量向左旋轉i個位置。例如,假設n=8,i=3,向量abcdefgh旋轉為向量defghabc。簡單的代碼使用一個n元的中間向量在n步內可完成該工作。你能否僅使用幾十個額外字節(jié)的內存空間,在正比于n的時間內完成向量的旋轉?

二、解決方案

思路一:將向量x中的前i個元素復制到一個臨時數(shù)組中,接著將余下的n-i個元素左移i個位置,然后再將前i個元素從臨時數(shù)組中復制到x中余下的位置。

性能:這種方法使用了i個額外的位置,如果i很大則產生了過大的存儲空間的消耗。

C++代碼實現(xiàn)如下:

/************************************************************************* 
  > File Name: vector_rotate.cpp 
  > Author: SongLee 
 ************************************************************************/ 
#include<iostream> 
#include<string> 
using namespace std; 
 
int main() 
{ 
  string s = "abcdefghijklmn"; 
  cout << "The origin is: " << s << endl; 
  // 左移個數(shù) 
  int i; 
  cin >> i; 
  if(i > s.size()) 
  { 
    i = i%s.size(); 
  } 
  // 將前i個元素臨時保存 
  string tmp(s, 0, i); 
  // 將剩余的左移i個位置 
  for(int  j=i; j<s.size(); ++j) 
  { 
    s[j-i] = s[j]; 
  } 
  s = s.substr(0, s.size()-i) + tmp; 
  cout << "The result is: "<< s << endl; 
  return 0; 
} 

思路二:定義一個函數(shù)將x向左旋轉一個位置(其時間正比于n),然后調用該函數(shù)i次。

性能:這種方法雖然空間復雜度為O(1),但產生了過多的運行時間消耗。

C++代碼實現(xiàn)如下:

/************************************************************************* 
  > File Name: vector_rotate_1.cpp 
  > Author: SongLee 
 ************************************************************************/ 
#include<iostream> 
#include<string> 
using namespace std; 
 
void rotateOnce(string &s) 
{ 
  char tmp = s[0]; 
  int i; 
  for(i=1; i<s.size(); ++i) 
  { 
    s[i-1] = s[i]; 
  } 
  s[i-1] = tmp; 
} 
 
int main() 
{ 
  string s = "abcdefghijklmn"; 
  cout << "The origin is: " << s << endl; 
  // 左移個數(shù) 
  int i; 
  cin >> i; 
  if(i > s.size()) 
  { 
    i = i%s.size(); 
  } 
  // 調用函數(shù)i次 
  while(i--) 
  { 
    rotateOnce(s); 
  } 
  cout << "The result is: "<< s << endl; 
  return 0; 
} 


思路三:移動x[0]到臨時變量t中,然后移動x[i]到x[0]中,x[2i]到x[i],依次類推,直到我們又回到x[0]的位置提取元素,此時改為從臨時變量t中提取元素,然后結束該過程(當下標大于n時對n取?;蛘邷p去n)。如果該過程沒有移動全部的元素,就從x[1]開始再次進行移動,總共移動i和n的最大公約數(shù)次。

性能:這種方法非常精巧,像書中所說的一樣堪稱巧妙的雜技表演??臻g復雜度為O(1),時間復雜度為線性時間,滿足問題的性能要求,但還不是最佳。

C++代碼實現(xiàn)如下:

/************************************************************************* 
  > File Name: vector_rotate_2.cpp 
  > Author: SongLee 
 ************************************************************************/ 
#include<iostream> 
#include<string> 
using namespace std; 
 
// 歐幾里德(輾轉相除)算法求最大公約數(shù) 
int gcd(int i, int j) 
{ 
  while(1) 
  { 
    if(i > j) 
    { 
      i = i%j; 
      if(i == 0) 
      { 
        return j; 
      } 
    } 
    if(j > i) 
    { 
      j = j%i; 
      if(j == 0) 
      { 
        return i; 
      } 
    } 
  } 
} 
 
int main() 
{ 
  string s = "abcdefghijklmn"; 
  cout << "The origin is: "<< s << endl; 
  // 左移個數(shù) 
  int i; 
  cin >> i; 
  if(i > s.size()) 
  { 
    i = i%s.size(); 
  } 
  // 移動 
  char tmp; 
  int times = gcd(s.size(), i); 
  for(int j=0; j<times; ++j) 
  { 
    tmp = s[j]; 
    int pre = j; // 記錄上一次的位置 
    while(1) 
    { 
      int t = pre+i; 
      if(t >= s.size()) 
        t = t-s.size(); 
      if(t == j) // 直到tmp原來的位置j為止 
        break; 
      s[pre] = s[t]; 
      pre = t; 
    } 
    s[pre] = tmp; 
  } 
  cout << "The result is: "<< s << endl; 
  return 0; 
} 

思路四:旋轉向量x實際上就是交換向量ab的兩段,得到向量ba,這里a代表x的前i個元素。假設a比b短。將b分割成bl和br,使br的長度和a的長度一樣。交換a和br,將ablbr轉換成brbla。因為序列a已在它的最終位置了,所以我們可以集中精力交換b的兩個部分了。由于這個新問題和原先的問題是一樣的,所以我們以遞歸的方式進行解決。這種方法可以得到優(yōu)雅的程序,但是需要巧妙的代碼,并且要進行一些思考才能看出它的效率足夠高。

//實現(xiàn)代碼(略) 

思路五:(最佳)將這個問題看做是把數(shù)組ab轉換成ba,同時假定我們擁有一個函數(shù)可以將數(shù)組中特定部分的元素逆序。從ab開始,首先對a求逆,得到arb,然后對b求逆,得到arbr。最后整體求逆,得到(arbr)r,也就是ba。

reverse(0, i-1)  /*cbadefgh*/
reverse(i, n-1) /*cbahgfed*/
reverse(0, n-1) /*defghabc*/

性能:求逆序的方法在時間和空間上都很高效,而且代碼非常簡短,很難出錯。

C++代碼實現(xiàn)如下:

/************************************************************************* 
  > File Name: vector_rotate.cpp 
  > Author: SongLee 
 ************************************************************************/ 
#include<iostream> 
#include<string> 
using namespace std; 
 
void reverse(string &s, int begin, int end) 
{ 
  while(begin < end) 
  { 
    char tmp = s[begin]; 
    s[begin] = s[end]; 
    s[end] = tmp; 
    ++begin; 
    --end; 
  } 
} 
 
int main() 
{ 
  string s = "abcdefghijklmn"; 
  cout << "The origin is: "<< s << endl; 
   
  int i; 
  cin >> i; 
  if(i > s.size()) 
  { 
    i = i%s.size(); 
  } 
 
  reverse(s, 0, i-1); 
  reverse(s, i, s.size()-1); 
  reverse(s, 0, s.size()-1); 
 
  cout << "The result is: "<< s << endl; 
  return 0; 
} 

三、擴展延伸

如何將向量abc旋轉變成cba?

和前面的問題類似,此向量旋轉對應著非相鄰內存塊的交換模型。解法很相似,即利用恒等式:cba = (arbrcr)r

注意:在面試或筆試時,如若出現(xiàn)向量旋轉(內存塊交換)問題,建議最好使用思路五答題,不僅高效而且簡潔。

相關文章

  • C語言實現(xiàn)時間戳轉日期的算法(推薦)

    C語言實現(xiàn)時間戳轉日期的算法(推薦)

    下面小編就為大家?guī)硪黄狢語言實現(xiàn)時間戳轉日期的算法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • C語言數(shù)據結構之雙鏈表&循環(huán)鏈表&靜態(tài)鏈表詳解

    C語言數(shù)據結構之雙鏈表&循環(huán)鏈表&靜態(tài)鏈表詳解

    這篇文章主要為大家詳細介紹了C語言數(shù)據結構中雙鏈表&循環(huán)鏈表&靜態(tài)鏈表的原理與使用,文中的示例代碼講解詳細,感興趣的可以了解一下
    2022-09-09
  • C語言實現(xiàn)關機小程序

    C語言實現(xiàn)關機小程序

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)關機小程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • Qt中connect()函數(shù)及用法詳解

    Qt中connect()函數(shù)及用法詳解

    connect() 函數(shù)就是Qt 框架中用于將信號(SIGNAL)和槽(SLOT)關聯(lián)起來的核心函數(shù),本文給大家介紹Qt中connect()函數(shù),感興趣的朋友跟隨小編一起看看吧
    2024-07-07
  • C++命名空間5種常見用法實例解析

    C++命名空間5種常見用法實例解析

    這篇文章主要介紹了C++命名空間5種常見用法實例解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-06-06
  • C++數(shù)據結構之哈希算法詳解

    C++數(shù)據結構之哈希算法詳解

    這篇文章主要為大家詳細介紹了C++數(shù)據結構中哈希算法的相關資料,文中的示例代碼講解詳細,具有一定的借鑒價值,希望對大家有所幫助
    2022-12-12
  • C語言實現(xiàn)程序開機自啟動

    C語言實現(xiàn)程序開機自啟動

    本文給大家分享的是一則C語言實現(xiàn)開機自啟動的代碼,主要是通過C來獲取程序路徑修改注冊表項來實現(xiàn),有需要的小伙伴可以參考下
    2016-01-01
  • C++訪問者模式模板函數(shù)無法重載的問題解決

    C++訪問者模式模板函數(shù)無法重載的問題解決

    本文主要介紹了C++訪問者模式模板函數(shù)無法重載的問題解決,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • 基于結構體與指針的詳解

    基于結構體與指針的詳解

    本篇文章是對結構體與指針進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • Dijkstra算法最短路徑的C++實現(xiàn)與輸出路徑

    Dijkstra算法最短路徑的C++實現(xiàn)與輸出路徑

    今天小編就為大家分享一篇關于Dijkstra算法最短路徑的C++實現(xiàn)與輸出路徑,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02

最新評論

兴业县| 大港区| 临澧县| 凌源市| 兰考县| 莱西市| 阿巴嘎旗| 辽宁省| 奉贤区| 四平市| 宁化县| 金湖县| 金门县| 金塔县| 波密县| 黎川县| 汨罗市| 衡东县| 吉安县| 彰化市| 乌兰察布市| 辽中县| 桂平市| 宣恩县| 滁州市| 交城县| 浮山县| 禹城市| 阿坝县| 丹棱县| 梅州市| 克拉玛依市| 华容县| 拜泉县| 依安县| 乌鲁木齐市| 江源县| 怀安县| 台湾省| 无极县| 孟津县|