目录
一、字符串旋转结果
1.1题目描述
写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。
例如:给定s1 =AABCD和s2 = BCDAA,返回1
给定s1=abcd和s2=ACBD,返回0.
例如:给定s1 =AABCD和s2 = BCDAA,返回1
给定s1=abcd和s2=ACBD,返回0.
1.2题目分析
(1)比较两个字符串的长度,如果长度不相等,那么它们一定不是旋转字符串,直接返回0。
(2)在字符串s1中寻找字符串s2的第一个字符出现的位置。我们可以使用一个循环来遍历字符串s1的每个字符,当找到与s2的第一个字符相等的字符时,我们记录下它的位置,并跳出循环。
(3)从记录的位置开始,逐个比较s1和s2的字。其中我们可以使用取模运算来实现循环比较。
(4)如果在比较过程中发现有任何一个字符不相等,就说明s2不是s1的旋转字符串,直接返回0。如果所有字符都相等,说明s2是s1的旋转字符串,返回1。
#include<stdio.h>
#include<string.h>
void LeftRound(char* str, int time)
{
//一次一次的挪动,time为总共移动的次数
int len = strlen(str);
time = time % len;//类比循环队列,因为移动一次和长度+1次的效果是一样的
for (int i = 0; i < time; i++)
{
int temp = str[0];
for (int j = 0; j < len - 1; j++)
{
str[j] = str[j + 1];
}
str[len - 1] = temp;
}
}
int main()
{
char str[] = "ABVCH";
LeftRound(str, 6);
printf("%s\n", str);
return 0;
}
1.3代码
#include<stdio.h>
#include<string.h>
// 判断字符串是否为旋转字符串
int IsSpin(char* s1, char* s2)
{
int len1 = strlen(s1);
int len2 = strlen(s2);
// 长度不相等,则一定不是旋转字符串
if (len1 != len2)
return 0;
// 找到字符串 s2 的第一个字符在 s1 中的位置
int startIndex = -1;
//使用一个循环来遍历字符串s1的每个字符
for (int i = 0; i < len1; i++)
{
//当找到与s2的第一个字符相等的字符时,我们记录下它的位置,并跳出循环
if (s1[i] == s2[0])
{
startIndex = i;
break;
}
}
// 如果没有找到匹配的字符,则不是旋转字符串
if (startIndex == -1)
return 0;
// 检查 s1 从 startIndex 开始的子串是否与 s2 相等
for (int j=0;j<len2;j++)
{
//从记录的位置开始,逐个比较s1和s2的字。其中我们可以使用取模运算来实现循环比较
if (s1[(startIndex + j) % len1] != s2[j])
{
return 0;
}
}
return 1;
}
int main()
{
char s1[] = "AABCD";
char s2[] = "ABCDA";
printf("%d\n", IsSpin(s1,s2));
char s3[] = "abcd";
char s4[] = "ACBD";
printf("%d\n", IsSpin(s4, s3));
return 0;
}
char s1[] = "AABCD";char s2[] = "ABCDA";结果会被误判为0。有问题。
这段代码中的问题是在查找字符串 s2 的第一个字符在字符串 s1 中的位置时,只找到了首次出现的匹配字符的位置。因此,对于某些特定情况下的旋转字符串,可能会导致误判。
1.4代码更正优化
解决方案是修改查找过程,使其能够找到所有匹配字符的位置,并逐个判断以确保整个子串都匹配成功。
#include<stdio.h>
#include<string.h>
// 判断字符串是否为旋转字符串
int IsSpin(char* s1, char* s2)
{
int len1 = strlen(s1);
int len2 = strlen(s2);
// 长度不相等,则一定不是旋转字符串
if (len1 != len2)
return 0;
// 找到字符串 s2 的第一个字符在 s1 中的位置的数组
int startIndex[256];
int count = 0;
//使用一个循环来遍历字符串s1的每个字符
for (int i = 0; i < len1; i++)
{
//当找到与s2的第一个字符相等的字符时,我们记录下它的位置,并跳出循环
if (s1[i] == s2[0])
{
startIndex[count++] = i;
}
}
// 如果没有找到匹配的字符,则不是旋转字符串
if (count == 0)
return 0;
// 逐个判断以各个可能的起始位置为开始的子串是否与 s2 相等
for (int j = 0; j < count; j++)
{
int index = startIndex[j];
int match = 1; // 标志位,判断子串是否完全匹配
for (int i = 0; i < len2; i++)
{
if (s1[(index + i) % len1] != s2[i])
{
match = 0;
break;
}
}
if (match)
{
return 1;
}
}
return 0;
}
int main()
{
char s1[] = "AABCD";
char s2[] = "ABCDA";
printf("%d\n", IsSpin(s1,s2));
char s3[] = "abcd";
char s4[] = "ACBD";
printf("%d\n", IsSpin(s4, s3));
return 0;
}
修正后的代码中,在找到字符串 s2 第一个字符在字符串 s1 中的位置时,将所有匹配字符的位置都保存在 startIndex 这个数组中。然后,对于每个可能的起始位置,逐个判断以该位置为开始的子串是否与 s2 完全匹配。只有当存在至少一个起始位置可以使得整个子串与 s2 相等时,才返回1表示是旋转字符串。这样修改后的代码能够正确处理包含重复字符的情况,避免了误判。
1.5字符串拼接和搜索
- 如果s2是s1旋转得到的字符串,那么将两个s1拼接起来形成的新字符串中,必然包含s2作为子串。
- 将两个s1拼接起来得到的新字符串记为combined。
- 如果s2是s1旋转得到的字符串,则s2必然是combined的一个子串。
#include<stdio.h>
#include<string.h>
// 判断字符串是否为旋转字符串
int IsSpin(char* s1, char* s2)
{
int len1 = strlen(s1);
int len2 = strlen(s2);
// 长度不相等,则一定不是旋转字符串
if (len1 != len2)
return 0;
// 将s1与自身拼接,组成一个新的字符串
char combined[256] = {0};
strcpy(combined, s1);
strcat(combined, s1);
// 判断s2是否是s1的子串,如果是返回1,否则返回0
return strstr(combined, s2) != NULL;
}
int main()
{
char s1[] = "AABCD";
char s2[] = "ABCDA";
printf("%d\n", IsSpin(s1,s2));
char s3[] = "abcd";
char s4[] = "ACBD";
printf("%d\n", IsSpin(s4, s3));
return 0;
}
strstr函数是C语言中的字符串函数,用于在一个字符串中查找指定子串的第一次出现位置。
char *strstr(const char *haystack, const char *needle);
参数说明:
haystack:要进行查找的字符串。
needle:要查找的子串。
返回值:
如果找到了子串,则返回子串在原字符串中的指针;如果未找到子串,则返回NULL。
strstr函数会从字符串 haystack 中开始查找子串 needle。如果找到了子串,则返回该子串在原字符串中的指针;如果未找到子串,则返回NULL。
二、杨辉三角形
#include <stdio.h>
int main()
{
//定义一个9行9列的二维整型数组
int data[9][9];
int i = 0;
int j = 0;
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
//数组所有元素都赋值为1
data[i][j] = 1;
}
}
//dp
for (i = 1; i < 9; i++)
{
for (j = 1; j < i; j++)
{
data[i][j] = data[i - 1][j] + data[i - 1][j - 1];
}
}
//输出数组所有元素
for (i = 0; i < 9; i++)
{
for (j = 0; j <= i; j++)
{
printf("%6d", data[i][j]);
}
printf("\n");
}
return 0;
}
三、猜凶手
某地发生了一起凶杀案,警察通过排查确定杀人凶手必为4个嫌疑犯中的一个。以下为4个嫌疑犯的供词:
A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说。
已知3个人说了真话,1个人说了假话。请编程来确定谁是凶手。
#include<stdio.h>
int main()
{
char killer;
for (killer = 'A'; killer <= 'D'; killer++)
{
if (((killer != 'A') + (killer == 'C') + (killer == 'D') + (killer != 'D')) == 3)
{
printf("凶手是:%c", killer);
}
}
return 0;
}
四、杨氏矩阵
有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,请编写程序在这样的矩阵中查找某个数字是否存在。
1 2 3 4 递增
5 6 7 8
9 10 11 12
递增
#include<stdio.h>
int Search(int arr[][4],int x,int y,int key)
{
int i = 0;
int j = y - 1;//先从右上角的元素开始进行比较
while (j >= 0&&i<x) //保证i和j是合法的
{
if (arr[i][j] > key)
{
j--;
}
else if(arr[i][j] < key)
{
i++;
}
else
{
return 1;//找到元素了
}
}
return 0;//没有找到元素
}
int main()
{
int arr[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
int ret = Search(arr, 3, 3, 2);
printf("%d\n", ret);
return 0;
}