上海龙凤419

C说话

C++完成一维向量扭转算法

时候:2024-07-31 13:49:07 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++完成自底向上的合并排序算法09-09

PHP完成抽奖几率算法09-13

权重随机算法的java完成08-13

PID算法的C说话完成07-19

《算法及其完成》的备课教案09-12

java通用组合算法若何完成09-12

JAVA简略挑选排序算法及完成10-02

C说话中完成KMP算法实例08-09

PHP完成山公选大王题目的算法10-28

java算法完成摆列组合的体例先容09-23