C++實現將字串迴圈左移n個位置

來源:互聯網
上載者:User
/**
 * @file 020_move_string.c
 * @author dinghuaneng
 * @date 2011.06.22
 * @brief 將字串進行向左旋轉,即迴圈左移的演算法實現。
 *        最後那種方法在時間和空間上都很高效,且代碼簡短,很難出錯。
 *        最節約空間和時間的方法來源:《編程珠璣》
 * @defgroup move_string
 * @{
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*********************** 最節約時間的方法 ************************/
/**
 * @brief 將字串向左旋轉n個位置
 * @param      str  待旋轉的字串
 * @param[in]  mov  需要旋轉的數量
 * @return 無
 */
void move_string_left(char *str, int mov)
{
    if (NULL == str || mov <= 0)
        return;
    char tmp[mov];
    int i;
    int len = strlen(str);
    if (len == 0)
        return;
    mov %= len;
    if (mov == 0)
        return;
    for (i = 0; i < sizeof tmp; i++)
        tmp[i] = str[i];
    tmp[i] = '\0';
    for (i = 0; i < len-mov; i++)
        str[i] = str[i+mov];
    for (; i < len; i++)
        str[i] = tmp[i-(len-mov)];
}

/**
 * @brief 將字串向右旋轉n個位置
 * @param      str  待旋轉的字串
 * @param[in]  mov  需要旋轉的數量
 * @return 無
 */
void move_string_right(char *str, int mov)
{
    if (NULL == str || mov <= 0)
        return;
    char tmp[mov];
    int i;
    int len = strlen(str);
    if (len == 0)
        return;
    mov %= len;
    if (mov == 0)
        return;
    for (i = len - mov; i < len; i++) {
        tmp[i-(len-mov)] = str[i];
    }
    tmp[i-(len-mov)] = '\0';
    for (i = len - 1; i >= mov; i--) {
        str[i] = str[i-mov];
    }
    for (; i >= 0; i--)
        str[i] = tmp[i];
}
/*********************** 最節約時間的方法 ************************/

/*********************** 最節約空間的方法 ************************/
/**
 * @brief 將字串向左旋轉1個位置
 * @param      str  待旋轉的字串
 * @param[in]  mov  需要旋轉的數量
 * @return 無
 */
void move_string_one_left(char *str)
{
    if (NULL == str)
        return;
    int  len = strlen(str);
    int  i;
    if (len == 0)
        return;
    char tmp = str[0];
    for (i=0; i<len-1; i++) {
        str[i] = str[i+1];
    }
    str[i] = tmp;
}

/**
 * @brief 將字串向右旋轉1個位置
 * @param      str  待旋轉的字串
 * @param[in]  mov  需要旋轉的數量
 * @return 無
 */
void move_string_one_right(char *str)
{
    if (NULL == str)
        return;
    int  len = strlen(str);
    if (len == 0)
        return;
    char tmp = str[len-1];
    int  i;
    for (i=len-1; i>0; i--) {
        str[i] = str[i-1];
    }
    str[i] = tmp;
}
/*********************** 最節約空間的方法 ************************/

/*********************** 最節約空間和時間的方法之一 ************************/
/**
 * @brief 返回數值i和j的最大公約數
 * @return 正確返回最大公約數,參數有問題返回-1
 */
int gcd(int i, int j)
{
    if (i<=0 || j<=0)
        return -1;
    while (i != j) {
        if (i > j)
            i -= j;
        else
            j -= i;
    }
    return i;
}

/**
 * @brief 將字串向左旋轉n個位置
 * @param      str  待旋轉的字串
 * @param[in]  mov  需要旋轉的數量
 * @return 無
 */
void move_string_fast_left(char *str, int mov)
{
    if (NULL == str || mov <= 0)
        return;
    int len = strlen(str);
    char tmp;
    if (!mov)
        return;
    mov %= len;
    if (!mov)
        return;
    int i, j, k;
    int g_cd = gcd(mov, len);
    for (i=0; i<g_cd; i++) {
        tmp = str[i];
        j = i;
        while (1) {
            k = j + mov;
            if (k >= len)
                k -= len;
            if (k == i)
                break;
            str[j] = str[k];
            j = k;
        }
        str[j] = tmp;
    }
}

/**
 * @brief 將字串向右旋轉n個位置
 * @param      str  待旋轉的字串
 * @param[in]  mov  需要旋轉的數量
 * @return 無
 */
void move_string_fast_right(char *str, int mov)
{
    if (NULL == str || mov <= 0)
        return;
    int len = strlen(str);
    if (!mov)
        return;
    mov %= len; // 修移動次數
    if (!mov)
        return;
    mov = len - mov;
    move_string_left(str, mov);
}
/*********************** 最節約空間和時間的方法之一 ************************/

/*********************** 最節約空間和時間的方法之二 ************************/
/**
 *  @brief 交換字串str中的從pos1開始和從pos2開始長度為num的兩部分元素。
 *         注意防止記憶體越界!
 *  @param      str  待交換部分字元的字串
 *  @param[in]  pos1 第一部分起始位置
 *  @param[in]  pos2 第二部分起始位置
 *  @param[in]  num  要交換的字元數量Architexa的反編譯和破解
 */
void swap_string(char *str, int pos1, int pos2, int num)
{
    char *str1 = str + pos1;
    char *str2 = str + pos2;
    int i;
       char tmp;
    for (i=0; i<num; i++) {
        tmp   = *str1;
        *str1 = *str2;
        *str2 = tmp;
        str1++;
        str2++;
    }
}

/**
 * @brief 用交換元素的方法進行向左旋轉(迴圈左移)
 * @param      str  待旋轉的字串
 * @param[in]  mov  需要旋轉的數量
 * @return 無
 */
void move_string_swap_left(char *str, int mov)
{
    if (NULL == str || mov <= 0)
        return;
    int len = strlen(str);
    if (!mov)
        return;
    mov %= len; // 修移動次數
    if (!mov)
        return;
    int i = mov;
    int j = len - mov;
    while (i != j) {
        if (i > j) {
            swap_string(str, mov-i, mov, j);
            i -= j;
        }
        else {
            swap_string(str, mov - i, mov - i + j, i);
            j -= i;
        }
    }
    swap_string(str, mov-i, mov, i);
}
/*********************** 最節約空間和時間的方法之二 ************************/

/*********************** 最節約空間和時間的方法之三 ************************/
/**
 * @brief 將字串str中從start開始至end結束的字元進行逆轉
 * @param     str  待逆轉部分字元的字串
 * @param[in] start  開始的位置
 * @param[in] end    結束的位置
 * @return 無
 */
void reverse(char *str, int start, int end)
{
    char *pos1 = str + start;
    char *pos2 = str + end;
    char  tmp;
    while (pos1 < pos2) {
        tmp   = *pos1;
        *pos1 = *pos2;
        *pos2 = tmp;
        pos1++;
        pos2--;
    }
}

/**
 * @brief  利用逆轉的方法對字串進行向左旋轉(迴圈左移)
 * @param      str  待旋轉的字串
 * @param[in]  mov  需要旋轉的數量
 * @return 無
 */
void move_string_reverse_left(char *str, int mov)
{
    if (NULL == str || mov <= 0)
        return;
    int len = strlen(str);
    if (!mov)
        return;
    mov %= len; // 修移動次數
    if (!mov)
        return;
    reverse(str, 0, mov-1);
    reverse(str, mov, len-1);
    reverse(str, 0, len-1);
}
/*********************** 最節約空間和時間的方法之三 ************************/
/** @} */

#if 1
int main(int argc, char **argv)
{
    char str[] = "Hello World!";
    int  n = atoi(argv[1]);
    int  i;
    move_string_reverse_left(str, n);
    printf("%s\n", str);
    return 0;
}
#endif

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.