将字符串循环左移右移

#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  要交换的字符数量 
 */  
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  

参考文章:
http://canlynet.iteye.com/blog/1095722

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值