【剑指offer】左旋字符串+拓展@面试题58

简介: 左旋字符串

@TOC
反爬链接
正文开始@一个人的乐队

左旋字符串

题目描述:

字符串左旋
题目内容:
实现一个函数,可以左旋字符串中的 k个字符。
例如:
ABCD左旋一个字符得到 BCDA
ABCD左旋两个字符得到 CDAB

法一:暴力求解

:yellow_heart:思路:
在这里插入图片描述

代码实现:

#include<stdio.h>
#include<assert.h>
#include<string.h>

void left_move(char* arr, int k)
{
    assert(arr);//断言--防止传入空指针
    int i = 0;
    int len = strlen(arr);
    for (i = 0; i < k; i++)
    {
        //左旋一个字符
        //1.保存第一个字符
        char tmp = *arr;
        int j = 0;
        //2.将后续的字符一次向前移动
        for (j = 0; j < len; j++)
        {
            *(arr + j) = *(arr + j + 1);
        }
        //3.把保存好的第一个字符放在末位
        *(arr + len - 1) = tmp;
    }
}
int main()
{
    char arr[] = "ABCD";
    int k = 0;
    scanf("%d", &k);
    left_move(NULL, k);
    printf("%s\n", arr);
    return 0;
}

注:

定义arr时,
:x:不可用`char* p =
"ABCD"; 的形式,因为"ABCD"`是常量字符串,不可更改,而这里要对字符串左旋,
:heavy_check_mark:而要用 char arr[] = "ABCD"; 以字符串初始化数组,字符数组可以被更改。

测试用例:
在这里插入图片描述

法二:逆序三次

:yellow_heart:思路:
在这里插入图片描述
代码实现:

#include<stdio.h>
#include<string.h>
#include<assert.h>
//逆序
void reverse(char* left, char* right)
{
    assert(left&&right);//断言
    while (left < right)
    {
        char tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;
    }
}
int main()
{
    char arr[] = "abcdef";
    int len = strlen(arr);
    int k = 2;
    reverse(arr, arr + k - 1);//逆序左边
    reverse(arr + k, arr + len - 1);//逆序右边
    reverse(arr, arr + len - 1);//逆序整体
    printf("%s\n", arr);
    return 0;
}

测试用例:
在这里插入图片描述

拓展:判断一个字符串是否为另一个字符串旋转后的字符串

题目描述:

字符串旋转结果
题目内容: 写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。
例如:
给定 s1 = AABCDs2 = BCDAA,返回 1
给定 s1 = abcds2 = ACBD,返回 0

AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD右旋一个字符得到DAABC

法一:穷举暴力求解

:yellow_heart:思路:

穷举: 每次旋转arr1的 一个字符,与arr2比较。 利用上文已经写好的 left_move函数。

代码实现:

#include<stdio.h>
#include<string.h>
#include<assert.h>

void reverse(char* left, char* right)
{
    assert(left&&right);
    while (left < right)
    {
        char tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;
    }
}

void left_move(char* arr, int k)
{
    assert(arr);
    int len = strlen(arr);
    k %= len;
    reverse(arr, arr + k - 1);//逆序左边
    reverse(arr + k, arr + len - 1);//逆序右边
    reverse(arr, arr + len - 1);//逆序整体
}

//判断一个字符串是否为另外一个字符串旋转之后的字符串
int is_left_move(char* arr1, char* arr2)
{
    assert(arr1&&arr2);
    int len = strlen(arr1);
    int i = 0;
    for (i = 0; i < len; i++)
    {
        left_move(arr1, 1);//每次旋转1个字符,比较
        if (strcmp(arr1, arr2) == 0)
        {
            return 1;
        }
    }
    return 0;
}
int main()
{
    char arr1[] = "AABCD";
    char arr2[] = "ABCD";
    int ret = is_left_move(arr1, arr2);
    if (ret == 1)
    {
        printf("Yes\n");
    }
    else
    {
        printf("No\n");
    }
    return 0;
}

测试用例:
在这里插入图片描述

法二:追加

:yellow_heart:思路:
在这里插入图片描述

简单介绍strncatstrstr的使用:
在这里插入图片描述
在这里插入图片描述
代码实现:

#include<stdio.h>
#include<string.h>
#include<assert.h>

int is_left_move(char* arr1, char* arr2)
{
    assert(arr1&&arr2);//断言
    int len1 = strlen(arr1);
    int len2 = strlen(arr2);
    //1.在arr1后追加一个arr1字符串
    strncat(arr1, arr1, len1);
    //2.判断arr2是否为arr1的子串且字符串长度要相等
    if (NULL != strstr(arr1, arr2) && len1 == len2)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
int main()
{
    char arr1[20] = "AABCD";//要保证arr1开辟空间足够大
    char arr2[] = "ABCD";
    int ret = is_left_move(arr1, arr2);
    if (ret == 1)
    {
        printf("Yes\n");
    }
    else
    {
        printf("No\n");
    }
    return 0;
}

测试用例:
在这里插入图片描述

本文完

相关文章
|
13天前
|
编译器 C语言
经典左旋,指针面试题
文章介绍了两种C语言实现字符串左旋的方法,以及如何使用C语言对整数数组进行奇偶数排序。通过实例演示了如何使用函数reverse_part和leftRound,以及在swap_arr中实现数组元素的重新排列。
24 0
|
2月前
|
安全 Java 编译器
【Java基础面试二十九】、说一说你对字符串拼接的理解
这篇文章讨论了Java中字符串拼接的四种常用方式(使用`+`运算符、`StringBuilder`、`StringBuffer`和`String`类的`concat`方法),每种方式适用的场景,以及在不同情况下的性能考量。
|
2月前
|
Java
【Java基础面试二十八】、使用字符串时,new和““推荐使用哪种方式?
这篇文章讨论了在Java中使用字符串时,推荐使用双引号`""`直接量方式而不是使用`new`操作符,因为`new`会在常量池之外额外创建一个对象,导致更多的内存占用。
|
2月前
|
安全 编译器 C++
【剑指offer】2.2编程语言(p22-p25)——面试题1:string赋值运算函数
【剑指offer】2.2编程语言(p22-p25)——面试题1:string赋值运算函数
|
3月前
|
存储 安全 Java
Java面试题:请解释Java中的字符串和字符串缓冲区?
Java面试题:请解释Java中的字符串和字符串缓冲区?
29 0
|
4月前
|
存储 算法 数据挖掘
深入解析力扣166题:分数到小数(模拟长除法与字符串操作详解及模拟面试问答)
深入解析力扣166题:分数到小数(模拟长除法与字符串操作详解及模拟面试问答)
|
5月前
【一刷《剑指Offer》】面试题 23:从上往下打印二叉树
【一刷《剑指Offer》】面试题 23:从上往下打印二叉树
|
5月前
【一刷《剑指Offer》】面试题 22:栈的压入、弹出系列
【一刷《剑指Offer》】面试题 22:栈的压入、弹出系列
|
5月前
|
算法
【一刷《剑指Offer》】面试题 21:包含 main 函数的栈
【一刷《剑指Offer》】面试题 21:包含 main 函数的栈
|
5月前
【一刷《剑指Offer》】面试题 20:顺时针打印矩阵
【一刷《剑指Offer》】面试题 20:顺时针打印矩阵