C语言编程 字符串的旋转(左旋右旋及判断)

此前不太熟悉这种类型的题目,特此做一个合计的方法总结。
包括字符串中字符的左旋(右旋),和判断一个字符串是否是由另一个字符串旋转(左旋或者右旋)而来。

一.字符串的左旋(右旋)

由于左旋和右旋思路一致,这里仅介绍左旋方法。
这种题目有两种思路:
1.首字符的后置以及其余元素的往前推置,循环重复此过程K次(k为左旋字符个数)。

eg:
字符串为“ABCDEF\0”,要旋转2个字符,
首先保存首字符到一个变量,然后把其余变量全部提前一位置放,即为“BCDEF \0”(此处注意,最后的终止符\0不要提前,留出一个空位)
再把用来保存的变量给字符串最后一个位置(除\0外),即为“BCDEFA\0”
再做一次此过程即为“CDEFGA \0”——》“CDEFGAB\0”

源代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void Exchange(char *str, int k)
{
    int i,m;
    char temp;
    char *sta;
    for (i = 0; i < k; i++)
    {
        sta = str;
        temp = *str;//保存首字符
        for (m = 0; m <= (int)strlen(str)-1; m++)//元素提前放置
        {
            *sta = *(sta + 1);
            sta++;
        }
        *(str+strlen(str)) = temp;//将首字符放置最后
    }
}

int main()
{
    int leng;
    printf("请输入要左旋几个字符\n");
    scanf("%d", &leng);
    char str[] = "ABCDEFG";
    Exchange(str,leng);
    printf("%s\n", str);
    system("pause");
    return 0;
}

2.三步旋转法
这种方法是由观察得来,旋转后的字符串有此规律:
旋转前“ABCDEFG”
旋转后“CDEFGAB”
将旋转后的字符逆置得
“CDEFGBA”
将未旋转的字符逆置得
“GFEDCBA”
再将全部字符逆置就得到了原来的字符串“ABCDEFG”
原字符串旋转时反向操作即可

源代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void reverse(char *left, char *right)//逆置函数
{
    char temp;
    while (left < right)
    {
        temp = *left;
        *left = *right;
        *right = temp;
        left++; right--;
    }
}
void Exchange(char *str, int leng)//三步逆置
{
    reverse(str, str + leng-1);
    reverse(str + leng, str+strlen(str)-1);
    reverse(str, str + strlen(str) - 1);
}
int main()
{
    int leng;
    printf("请输入要左旋几个字符\n");
    scanf("%d", &leng);
    char str[] = "ABCDEFG";
    Exchange(str,leng);
    printf("%s\n", str);
    system("pause");
    return 0;
}

二.判断一个字符串是否是由另一个字符串旋转而来
1.第一种思路是不借助字符串库函数,将需要判断的字符串按照三步逆置法判断是否和原字符串相同,但是这种方法效率较差,而且时间复杂度高。

源代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void reverse(char *left,char *right)
{
    char temp;
    while (left < right)
    {
        temp = *left;
        *left = *right;
        *right = temp;
        left++; right--;
    }
}
int judgeStr(char str1[],char str2[],char str3[])
{
    int i,m=0,sum=0,s;
    char *sta ;
    char *fina ;
    int length = strlen(str1);
    for (i = 0; i <(int)strlen(str2); i++)
    {
        str3[i] = str2[i];
    }
    for (i = 0; i <= (int)strlen(str1) - 1; i++)
    {
        sta = str3;
        fina = str3 + strlen(str1) - 1;
        reverse(sta, sta + i);
        reverse(sta + i + 1, fina);
        reverse(sta, fina);
        for (; m < (int)strlen(str1); m++)
        {
            if (str1[m] != str3[m])
            {
                sum++;
                break;
            }
        }
        for (s = 0; s<(int)strlen(str2); s++)
        {
            str3[s] = str2[s];
        }
        if (sum == 4)
        {
            return 0;
        }
    }
    return 1;
}
int main(void)
{
    char str1[] = "ABCDE";
    char str2[] = "BCDEA";
    char str3[] = "BACDE";
    char stra[] = "AAAAA";
    int judge;
    judge = judgeStr(str1, str2,stra);
    if (judge == 1)
    {
        printf("str2是由str1旋转得来的\n");
    }
    else
    {
        printf("str2不是由str1旋转得来的\n");
    }
    judge = judgeStr(str1, str3,stra);
    if (judge == 1)
    {
        printf("str3是由str1旋转得来的\n");
    }
    else
    {
        printf("str3不是由str1旋转得来的\n");
    }
    system("pause");
    return 0;
}

2.使用字符串库函数解决
使用此方法需要注意到一个规律:
一个字符串后面再接一个和自身相同的字符串后,此字符串中就出现了所有旋转可以得到的结果。

eg:
A B C D A B C D,其中有所有的“ABCD”旋转结果,BCDA(2~5),CDAB(3~6),DABC(4~7)。

所以做法就是利用库函数将原字符串拼接一个自身,再在字符串中查找需要判断的字符串即可。

源代码:

#include<stdio.h>
#include<string.h>
int judge(char *str1, char *str2)
{
  strncat(str1, str1, strlen(str1));//原字符串拼接本身
    char *result = strstr(str3, str2);//查找目标字符串
    if (result == NULL)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}
int main()
{
    char str1[] = "ABCDE";
    char str2[] = "CDEAB";
    char str3[] = "DEBAC";
    int result = judge(str1, str2);
    if (result == -1)
    {
        printf("str2不是由str1旋转得到\n");
    }
    else
    {
        printf("str2是由str1旋转得到\n");
    }
    result = judge(str1, str3);
    if (result == -1)
    {
        printf("str3不是由str1旋转得到\n");
    }
    else
    {
        printf("str3是由str1旋转得到\n");
    }
    system("pause");
    return 0;
}

原文地址:https://blog.51cto.com/14232799/2386233

时间: 2024-10-12 21:10:38

C语言编程 字符串的旋转(左旋右旋及判断)的相关文章

字符串左旋右旋——三步旋转法和移相法

题目:实现一个函数,可以左旋字符串中的k个字符. AABCD左旋一个字符得到ABCDA AABCD左旋两个字符得到BCDAA 方法一:三步旋转法 左旋程序思路:首先根据画图得知左旋后的结果,然后在分析实现的简约步骤: 第一步:字符串全逆序: 第二步:左边的字符串逆序: 第三步:右边的字符串逆序: 举例:左旋K=1个字符: 首先是头文件和主函数部分: #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<windows.h

数组,链表,字符串 的旋转(未完待续)

字符串操作 题目一: 字符串的旋转(左旋操作) 给定一个字符串,要求把字符串前面的若干个字符移动到字符串的尾部,如把字符串“abcdef”前面的2个字符'a'和'b'移动到字符串的尾部,使得原字符串变成字符串“cdefab”.请写一个函数完成此功能,要求对长度为n的字符串操作的时间复杂度为 O(n),空间复杂度为 O(1). 题目出处:程序员编程艺术:面试和算法心得 微软面试100题 第二十六题 剑指Offer 第42题,翻转字符串vs 左旋转字符串 分析: 解法一:暴力法————循环移位,时间

C语言:判断一个字符串是不是另一个字符串的旋转字符串

例如:给定s1 = AABCD和s2 = BCDAA,返回1, 给定s1=abcd和s2=ACBD,返回0. AABCD左旋一个字符得到ABCDA AABCD左旋两个字符得到BCDAA AABCD右旋一个字符得到DAABC AABCD右旋两个字符得到CDAAB 分析题目之后我们发现,一个字符串有左旋转和右旋转两种.左旋转之后的字符串在原字符串拼接后的新字符串中:右旋转之后的字符串拼接之后可以找到源字符串. 这里我们会使用两个库函数strncat和strstr,关于两个函数的定义请自己查找. 字符

判断一个字符串是否为另外一个字符串左旋或右旋之后的字符串

题目: 判断一个字符串是否为另外一个字符串旋转之后的字符串.例如:给定s1 = abcdef和s2 = cdefab,返回1,给定s1=abcd和s2=ACBD,返回0. abcdef左旋一个字符得到bcdefa abcdef左旋两个字符得到cdefab abcdef右旋一个字符得到fabcde abcdef右旋两个字符得到efabcd 题目分析: 根据这个题目,我们能够和字符串的左旋和右旋联系起来,如果把给定的字符串拷贝一份放在给定字符串之后,例如:给定字符串abcdef,经过拷贝后得到字符串

编程算法 - 左旋转字符串 代码(C)

左旋转字符串 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部. 请定义一个函数实现字符串左旋转操作的功能. 编程珠玑, 首先翻转前部分, 再翻转后部分, 最后全部翻转. 代码: /* * main.cpp * * Created on: 2014.6.12 * Author: Spike */ /*eclipse cdt, gcc 4.8.1*/ #include <stdio

矩阵旋转(左旋,右旋)

#include <iostream> using namespace std; const int M = 3; //行数 const int N = 5; //列数 int main() { int a[M][N] = {{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}}; int *p = a[0]; //正常输出矩阵 for(int i=0;i<M;i++) { for(int j=0;j<N;j++) { cout<<a[i]

【C语言】判断一个字符串是否是一个字符串的旋转字符串

//判断一个字符串是否是一个字符串的旋转字符串 //利用库函数实现 #include <stdio.h> #include <string.h> #include <assert.h> int IsRotate(char *str1, const char *str2) { assert(str1); assert(str2); strncat(str1, str1,strlen(str1)); if (NULL == strstr(str1, str2)) retur

华为C语言编程规范

DKBA华为技术有限公司内部技术规范DKBA 2826-2011.5C语言编程规范2011年5月9日发布 2011年5月9日实施华为技术有限公司Huawei Technologies Co., Ltd.版权所有 侵权必究All rights reserved密级:confidentiality levelDKBA 2826-2011.52011-06-02 华为机密,未经许可不得扩散 Huawei Confidential 第2页,共61页Page 2 , Total61修订声明Revision

linux 操作系统下c语言编程入门

2)Linux程序设计入门--进程介绍 3)Linux程序设计入门--文件操作 4)Linux程序设计入门--时间概念 5)Linux程序设计入门--信号处理 6)Linux程序设计入门--消息管理 7)Linux程序设计入门--线程操作 8)Linux程序设计入门--网络编程 9)Linux下C开发工具介绍 1)Linux程序设计入门--基础知识 Linux下C语言编程基础知识 前言: 这篇文章介绍在LINUX下进行C语言编程所需要的基础知识.在这篇文章当中,我们将 会学到以下内容: 源程序编