<pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

          <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

          <p id="bbfd9"></p>

          <p id="bbfd9"><cite id="bbfd9"></cite></p>

            <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

            <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
            <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
            C語言

            C++實現一維向量旋轉算法

            時間:2025-04-29 12:12:34 C語言 我要投稿
            • 相關推薦

            C++實現一維向量旋轉算法

              C++實現一維向量旋轉的算法的怎么編程的呢?下面內容由小編為大家介紹C++實現一維向量旋轉算法,供大家參考!

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

              一、問題描述

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

              二、解決方案

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

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

              C++代碼實現如下:

              /*************************************************************************

              > File Name: vector_rotate.cpp

              > Author: SongLee

              ************************************************************************/

              #include

              #include

              using namespace std;

              int main()

              {

              string s = "abcdefghijklmn";

              cout << "The origin is: " << s << endl;

              // 左移個數

              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[j-i] = s[j];

              }

              s = s.substr(0, s.size()-i) + tmp;

              cout << "The result is: "<< s << endl;

              return 0;

              }

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

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

              C++代碼實現如下:

              /*************************************************************************

              > File Name: vector_rotate_1.cpp

              > Author: SongLee

              ************************************************************************/

              #include

              #include

              using namespace std;

              void rotateOnce(string &s)

              {

              char tmp = s[0];

              int i;

              for(i=1; i

              {

              s[i-1] = s[i];

              }

              s[i-1] = tmp;

              }

              int main()

              {

              string s = "abcdefghijklmn";

              cout << "The origin is: " << s << endl;

              // 左移個數

              int i;

              cin >> i;

              if(i > s.size())

              {

              i = i%s.size();

              }

              // 調用函數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取模或者減去n)。如果該過程沒有移動全部的元素,就從x[1]開始再次進行移動,總共移動i和n的最大公約數次。

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

              C++代碼實現如下:

              /*************************************************************************

              > File Name: vector_rotate_2.cpp

              > Author: SongLee

              ************************************************************************/

              #include

              #include

              using namespace std;

              // 歐幾里德(輾轉相除)算法求最大公約數

              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;

              // 左移個數

              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

              {

              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的兩個部分了。由于這個新問題和原先的問題是一樣的,所以我們以遞歸的方式進行解決。這種方法可以得到優雅的程序,但是需要巧妙的代碼,并且要進行一些思考才能看出它的效率足夠高。

              //實現代碼(略)

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

              ?

              1

              2

              3

              reverse(0, i-1) /*cbadefgh*/

              reverse(i, n-1) /*cbahgfed*/

              reverse(0, n-1) /*defghabc*/

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

              C++代碼實現如下:

              /*************************************************************************

              > File Name: vector_rotate.cpp

              > Author: SongLee

              ************************************************************************/

              #include

              #include

              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


            【C++實現一維向量旋轉算法】相關文章:

            C++實現自頂向下的歸并排序算法03-24

            C++實現自底向上的歸并排序算法03-14

            堆排序算法及用C++實現基于最大堆的堆02-12

            C++選擇排序算法實例02-25

            權重隨機算法的java實現08-13

            PHP實現抽獎概率算法03-21

            C++插入排序算法實例06-02

            C++歸并排序算法實例02-09

            C++冒泡排序算法實例詳解06-09

                    <pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

                    <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

                    <p id="bbfd9"></p>

                    <p id="bbfd9"><cite id="bbfd9"></cite></p>

                      <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

                      <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
                      <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
                      飘沙影院