【数据结构刷题】消失的数字和轮转数组(下)

简介: 【数据结构刷题】消失的数字和轮转数组(下)

题型2:写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。


写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。

例如:给定s1 =AABCD和s2 = BCDAA,返回1

给定s1=abcd和s2=ACBD,返回0.

AABCD左旋一个字符得到ABCDA

AABCD左旋两个字符得到BCDAA

AABCD右旋一个字符得到DAABC


方法1:根据strcmp函数比较两者字符串的ascll码值。

具体实现思路是:

通过循环将arr1向左移动一位反复这个过程,并使用strcmp函数比较移动后的arr1arr2

是否相等,如果相等则返回1,表示可以通过左移变成arr2

如果遍历完整个arr1后仍无法得到arr2,则返回0,表示无法通过左移变成arr2

int is_left_move(char arr1[], char arr2[])
{
  int len = strlen(arr1);
  int i = 0;
  for (i = 0; i < len; i++)//要是遍历完arr1数组,也没有出现和arr2相同的字符串那就返回0
  {
    char tmp = arr1[0];
    int j = 0;
    for (j = 0; j < len-1; j++)
    {
      arr1[j] = arr1[j + 1];
    }
    arr1[len-1] = tmp;
    if (strcmp(arr1, arr2) == 0)//比较ascll码值
    {
      return 1;
    }
  }
  return 0;
}
#include<stdio.h>
int main()
{
  char arr1[20] = "abcdef";//abcdefabcdef
  char arr2[] = "cdefab";
  int ret = is_left_move(arr1, arr2);
  if (ret == 1)
  {
    printf("yes\n");
  }
  else
  {
    printf("no\n");
  }
  return 0;
}

说明:

该代码实现了一个函数is_left_move,用于判断一个字符串arr1是否能通过左移若干个字符的方式变成另一个字符串arr2

在这个例子中,"abcdef"可以通过左移两个字符的方式变成"cdefab",因此最终输出"yes"。

执行:

11486d622dd847c3a05c1e95f69cde41.png


方法2:通过strstr函数查找

关于strstr的说明:

strstr是C语言中的一个字符串查找函数,用于在一个字符串中查找另一个字符串的出现位置。

该函数的原型为:char *strstr(const char *str1, const char *str2);

其中,str1是要查找的字符串,str2是要在str1中查找的目标字符串,函数返回值是一个指向str1中第一次出现str2的指针,如果str2未出现,则返回NULL。


在查找str2时,函数会从str1的开头开始逐个比较字符,一旦发现不匹配的字符,就会重新从下一个字符开始继续匹配,直到找到第一个匹配的子串或者str1中的所有字符都被比较完为止。如果str2为空字符串,则函数返回str1本身。


代码实现:

int is_left_move(char arr1[], char arr2[])
{
  int len1 = strlen(arr1);
  int len2 = strlen(arr2);
  if (len1 != len2)
    return  0;
  strncat(arr1, arr1, len1);
    if (strstr(arr1, arr2))
      return 1;
    else
      return 0;
}
#include<stdio.h>
int main()
{
  char arr1[20] = "abcdef";
  char arr2[] = "cdefab";
  int ret = is_left_move(arr1, arr2);
  if (ret == 1)
  {
    printf("yes\n");
  }
  else
  {
    printf("no\n");
  }
  return 0;
}


简述一下此函数在这题的作用:

if (len1 != len2)

       return  0;


在arr1[]="abcdef"前提下,如果arr2[]=“cdef”那么在


if (strstr(arr1, arr2))

           return 1;

       else

           return 0;


函数中就会认为arr2是arr1的字串,直接返回1,但这样是不对的,题目的意思是说arr1能否左旋转


简述一下此函数在这题的作用:

strncat(arr1, arr1, len1);

在这个函数中,strncat(arr1, arr1, len1) 的作用是将 arr1 的内容复制一遍添加到 arr1 的末尾,从而形成一个新的字符串。这样做是为了处理环形移位的情况,即当将 arr1 的某些字符移动到末尾时,它们将出现在开头。通过将 arr1 复制一遍添加到末尾,可以将环形移位转换为普通的移位,从而简化字符串比较的逻辑。

代码执行:

6b19395f74864e419427cf194e05aa14.png


题型3:给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。


6b00238c93614310bfeee101482d800e.png

思路1: 实际上就是右旋字符串,跟上面第一题的左旋字符串有着异曲同工之妙。

5894e960daff46b5b8b2073d1896ddcc.png

void rotate(int* nums, int numsSize, int k){
       int i=0;
       k=k%numsSize;
     for(i=0;i<k;i++)
     {
       int j=0;
       int tmp=nums[numsSize-1];
       for(j=numsSize-1;j>0;j--)
          {
          nums[j]=nums[j-1];
          }
          nums[0]=tmp;
     }
}

这种方式属于暴力求解,要用较多的时间,但实际上放到vs2019上可以执行

力扣运行:

8f67c9ecf3de400c893ec2ee3c9f85c4.png

vs2019编译器:

#include<stdio.h>
void rotate(int* nums, int numsSize, int k) {
    int i = 0;
    k = k % numsSize;
    for (i = 0; i < k; i++)
    {
        int j = 0;
        int tmp = nums[numsSize - 1];
        for (j = numsSize - 1; j > 0; j--)
        {
            nums[j] = nums[j - 1];
        }
        nums[0] = tmp;
    }
}
int main()
{
    int nums[] = { 1, 2, 3, 4, 5, 6, 7 };
    int k = 0;
    scanf("%d", &k);
    int sz = sizeof(nums) / sizeof(nums[0]);
    rotate(nums, sz,  k);
    for (int i = 0; i < sz; i++) {
        printf("%d", nums[i]);
    }
}


代码执行:

f53f2ea06ca44acbbc90801a6cbe2c90.png

思路2:三步旋转法(搞清楚左部分和右部分)

93dc5018e40343c7a4c879c2ee7667fb.png

6c2d63cdea5549228a6ced63cde9f23d.png


代码实现:

void reverse(int*a,int left, int right)
{
    while (left < right)
    {
      int tmp = a[left];
        a[left] = a[right];
        a[right] = tmp;
        left++;
        right--;
    }
}
void rotate(int* nums, int numSize, int k)
{
    if (k > numSize)
        k %= numSize;
    reverse(nums, 0, numSize - k - 1);
    reverse(nums, numSize - k , numSize - 1);
    reverse(nums, 0, numSize  - 1);
}
int main()
{
    int nums[] = {1,2,3,4,5,6,7};
    int k = 0;
    scanf("%d", &k);
    int sz = sizeof(nums) / sizeof(nums[0]);
    rotate(nums, sz,  k);
    for (int i = 0; i < sz; i++) {
        printf("%d", nums[i]);
    }
}


思路3:空间换时间

思路:

4f3141639f85401bbeea4379b37da4b9.png

简述一下memcpy的作用:

在 C 语言中,memcpy是一个函数,用于在内存之间复制一定数量的字节。其函数原型为:

void* memcpy(void* destination, const void* source, size_t num);

其中,destination 是目标内存区域的指针,source 是源内存区域的指针,num 是要复制的字节数。

memcpy 函数的作用是将源内存区域中的 `num` 个字节复制到目标内存区域中。如果源和目标内存区域重叠,行为是未定义的。


以下是一个示例:

#include <stdio.h>
#include <string.h>
int main() {
    char source[] = "hello";
    char destination[6];
    memcpy(destination, source, 6);
    printf("%s\n", destination);
    return 0;
}


输出结果为:

b2dc05793e6e4457b2b9e2d559848108.png

在这个示例中,memcpy 函数将 source 数组中的 5 个字符复制到 destination 数组中。由于 destination 数组长度为 6,所以需要复制 6 个字节,其中最后一个字节会被设置为 NULL 字节,即字符串结束标志。最终输出结果为 hello

memcpy 函数通常用于需要将一个内存区域的数据复制到另一个内存区域的情况。例如,当你需要对一个字符串进行操作时,可以使用 memcpy 函数将其复制到一个缓冲区中进行处理,以避免改变原始字符串的值。此外,memcpy 函数还可以用于将任何类型的数据复制到内存中。

思路3代码实现:

#include<stdio.h>
void rotate(int* nums, int numSize, int k)
{
    if (k > numSize)
        k %= numSize;
    int* tmp = (int*)malloc(sizeof(int) * numSize);
    memcpy(tmp+k,nums,sizeof(int)*(numSize-k));
    memcpy(tmp,nums + numSize - k, sizeof(int) * (k));
    memcpy(nums, tmp, sizeof(int) * (numSize));
    free(tmp);
    tmp=NULL;
}
int main()
{
    int nums[] = {1,2,3,4,5,6,7};
    int k = 0;
    scanf("%d", &k);
    int sz = sizeof(nums) / sizeof(nums[0]);
    rotate(nums, sz,  k);
    for (int i = 0; i < sz; i++) {
        printf("%d", nums[i]);
    }
}


代码执行:

5ef2e1404ba842eb875dba0545c210ca.png

本章完,如有错误欢迎大佬指正。

相关文章
|
14天前
|
存储 人工智能 算法
C 408—《数据结构》算法题基础篇—数组(通俗易懂)
408考研——《数据结构》算法题基础篇之数组。(408算法题的入门)
58 23
|
3月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
99 5
|
3月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
81 4
|
4月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
72 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
4月前
|
存储 算法 定位技术
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
这篇文章主要介绍了稀疏数组和队列的概念、应用实例以及如何使用数组模拟队列和环形队列的实现方法。
50 0
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
|
3月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
328 9
|
3月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
53 1
|
1月前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
142 77
|
2天前
|
DataX
☀☀☀☀☀☀☀有关栈和队列应用的oj题讲解☼☼☼☼☼☼☼
### 简介 本文介绍了三种数据结构的实现方法:用两个队列实现栈、用两个栈实现队列以及设计循环队列。具体思路如下: 1. **用两个队列实现栈**: - 插入元素时,选择非空队列进行插入。 - 移除栈顶元素时,将非空队列中的元素依次转移到另一个队列,直到只剩下一个元素,然后弹出该元素。 - 判空条件为两个队列均为空。 2. **用两个栈实现队列**: - 插入元素时,选择非空栈进行插入。 - 移除队首元素时,将非空栈中的元素依次转移到另一个栈,再将这些元素重新放回原栈以保持顺序。 - 判空条件为两个栈均为空。
|
1月前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
43 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】

热门文章

最新文章