左旋或右旋字符串的思路,例ABCDEF,左旋两位为CDEFAB

  1. 使用暴力旋转方法,例如左旋,即把第一个字符存放到临时变量中,再依次把后面的字符串往前挪动,最后把临时变量中存放的字符放到最后一个位置

void left_reverse(char* arr, int k)
{

int i = 0;
int len = strlen(arr);
for ( i = 0; i < k; i++)//控制左旋的次数
{
    char temp = *arr;//将数组首元素保存在临时变量中
    int j = 0;
    for ( j = 0; j < len-1; j++)//依次挪动后面的元素,使其覆盖前一个元素
    {
        *(arr + j) = *(arr + j + 1);
    }
    *(arr + len - 1) = temp;
}

}

三步法,第一步,将需要左旋的字符整体逆序,第二步,将剩余的字符串整体逆序,第三部,将二者组合成的新字符串整体逆序即可
void reverse(char left, char right)//逆序函数,利用左右指针交换元素,左右指针从两端向中间移动
{

assert(left != NULL);
assert(right != NULL);
while (left < right)
{
    char temp = *left;
    *left = *right;
    *right = temp;
    left++;
    right--;
}

}
void left_reverse1(char* arr, int k)//实现三部逆序
{

assert(arr);
int len = strlen(arr);
reverse(arr, arr + k - 1);//先逆序前k个元素
reverse(arr + k, arr + len - 1);//逆序剩下的元素
reverse(arr, arr + len - 1);//将逆序完成的两部分合起来整体逆序即可

}



2. 比较一个字符串是否为另一个字符串左旋后的结果,目前有两种方法:
  a.暴力求解法:讲被比较的字符串依次旋转,把旋转的每种结果都和另外一个已经旋转的字符串比较
  

int is_leftrverse(char* s1, char* s2) //传入进行比较的两个字符串
{
    int len = strlen(s1);
    int i = 0;
    for ( i = 0; i < len-1; i++)//将被比较的字符串逐一左旋
    {
        left_reverse1(s1, 1);//为了保证字符串顺序不被破坏,所以每次只旋转一个
        int ret = strcmp(s1, s2);//调用strcmp函数比较两个字符串是否相等
        if (ret == 1)
        {
            return 1;//相等则返回1
        }
    }
    return 0;//若旋转完所有字符串后仍然无法使二者相等,则返回0
}


  
  b.使用叠加法,例如,将ABCDEF扩充成ABCDEFABCDEF,若CDEFBA是扩充后的一个子串,则判断字符串2确实是字符串1旋转若干次数的结果,其中使用到库函数strncat()以及strstr();
  

int is_leftrverse1(char s1, char s2)
{

int len1 = strlen(s1);
int len2 = strlen(s2);
if (len1 != len2)
{
    return 0;
}
strncat(s1, s1, len1);//给s1追加字符,例如使得abcdef变为abcdefabcdef
char* ret = strstr(s1, s2);//判断s2指向的字符串是否是s1的子串
if (ret == NULL)
{
    return 0;
}
else
{
    return 1;
}

}
*注释:为什么不用strcat函数,因为strcat函数的在追加字符串或数组时,末尾的/0会被覆盖掉。导致尾部追加的字符串在复制原字符串时无法复制/0,导致最终的字符串缺少/0,所以只能使用strncat函数
左旋或右旋字符串的思路,例ABCDEF,左旋两位为CDEFAB_第1张图片

你可能感兴趣的:(c)