《C++的十万个为什么》[57]怎么编写一个字符串循环移动函数?——兼谈时间和空间之间永恒的战争

《C++的十万个为什么》[57]如何编写一个字符串循环移动函数?——兼谈时间和空间之间永恒的战争
本帖最后由 TouchStoneStudio 于 2013-01-03 18:57:02 编辑
原文来自:
http://chenlq.net/dev/cpp-why/57-how-to-write-a-string-loop-mobile-function-also-on-the-eternal-war-between-time-and-space.html

Q:

一位同学问了我这样一个关于内存操作的问题:

     
    
    实现字符串右移几位
    #include <iostream>
    using namespace std;
    int main()
    {
    int    n; //移位数
    int    index=0; //记录待移位字符串的数组下标
    int    move_num=0; //记录简化的移位数
    char   str[]="test"; //待移位字符串
    int    length = strlen(str);
    char  *new_str= new char[length+1];
    if (new_str == nullptr)
    {
    return    1;
    }
    cin >> n;
    move_num = n % length;
    while (*(str + index))
    {
    new_str[(index + move_num) % length] = *(str + index);
    index++;
    }
    new_str[length+1] = '\0'; //别忘记加上结束符
    cout << new_str << endl;
    delete[]  new_str;//发生运行时错误
    return   0;
    }

A:

从他的代码中,我没有发现内存操作的问题,反倒是发现他在实现字符串移动的时候,即有点浪费时间(逐个字符地移动,浪费时间)又有点浪费空间(申请了一个字符串长度的内存空间来作为临时存储的区域)。
通常,我们都是用时间复杂度和空间复杂度来衡量一个算法的优劣。因而,在设计算法的时候,我们往往有两个不同方向的设计方向。就这个问题而言,如果我们考虑空间优先(比如,这个程序可能运行在内存资源紧张的平台),也就是使用尽量少的内存空间来实现功能,多花一点时间没有关系。我们可以仅仅使用一个字符来作为中转交换的临时变量,而不是整个字符串长度的中转交换临时空间。
 

void movestr(char* str,const int n)
{
    const int LEN = strlen(str);
    for(int i = 0;i < n; ++i) // 逐个移动字符
    {
        char tmp = str[0]; // 中转的临时空间,备份第一个字符
        for(int i = 0;i < LEN; ++i) // 移动后继字符
        {
            str[i] = str[i+1];
        }
        str[LEN-1] = tmp;
    }
}

然而,就计算机硬件的发展而言,内存资源已经不再是那么昂贵了,所以,。。。

请访问原文继续。。
iostream C++  

------解决方案--------------------
来接分《C++的十万个为什么》[57]怎么编写一个字符串循环移动函数?——兼谈时间和空间之间永恒的战争