给定主串s和模式串p,编写程序输出p在s中出现的首位置,若p不在s中则输出-1。字符串下标从0开始。
时间: 2023-04-24 20:00:26 浏览: 151
可以使用字符串匹配算法来解决这个问题,比如暴力匹配、KMP算法、Boyer-Moore算法等。以下是暴力匹配的实现代码:
```python
def find_pattern(s, p):
n, m = len(s), len(p)
for i in range(n - m + 1):
j =
while j < m and s[i+j] == p[j]:
j += 1
if j == m:
return i
return -1
```
其中,n和m分别是主串s和模式串p的长度,i是主串中当前匹配的起始位置,j是模式串中当前匹配的位置。在while循环中,如果当前字符匹配成功(即s[i+j] == p[j]),则继续匹配下一个字符,否则跳出循环,i++后继续在主串中匹配下一个子串。如果模式串中所有字符都匹配成功,则说明找到了匹配的位置,返回i;否则,返回-1表示未找到。
例如,对于主串s="hello world"和模式串p="world",调用find_pattern(s, p)会返回6,表示模式串p在主串s中出现的首位置为6。如果模式串p="python",则返回-1,表示模式串p不在主串s中出现。
相关问题
用C语言实现字符串模式匹配,给定主串s和模式串p,编写程序输出p在s中出现的首位置,若p不在s中则输出-1。字符串下标从0开始。 输入格式: 输入为2行,第1行主串s,第2行为模式串p。主串和模式串...
好的,这是一个经典的字符串匹配问题,可以使用暴力匹配算法或者KMP算法来解决。
以下是使用暴力匹配算法的C语言代码实现:
```c
#include <stdio.h>
#include <string.h>
int strMatch(char s[], char p[]) {
int n = strlen(s);
int m = strlen(p);
for (int i = 0; i <= n-m; i++) {
int j;
for (j = 0; j < m; j++) {
if (s[i+j] != p[j]) {
break;
}
}
if (j == m) {
return i;
}
}
return -1;
}
int main() {
char s[100], p[100];
scanf("%s%s", s, p);
int pos = strMatch(s, p);
printf("%d\n", pos);
return 0;
}
```
代码思路是:先计算出主串和模式串的长度,然后从主串的第一个字符开始,逐一比较主串和模式串中对应位置的字符,如果相同则继续比较下一个字符,否则从主串的下一个位置开始重新匹配。如果模式串全部匹配完,则说明匹配成功,返回该子串在主串中出现的位置;否则继续在主串中寻找下一个子串进行匹配,直到主串中没有剩余的子串可供匹配。
需要注意的是,该算法的时间复杂度是O(n*m),其中n为主串长度,m为模式串长度,因此在处理大规模的字符串匹配问题时,该算法的效率较低。KMP算法是一种更高效的字符串匹配算法,但涉及到的知识点较为复杂,需要更多的学习和掌握。
3.11 已知fosc=12MHz。要求在80C51 P1.0、P1.1、P1.2和P1.3引脚分别输出周期为500μs.1ms、5ms 和 10ms 的脉冲方波。试编制程序
要实现这个功能,我们可以利用80C51单片机的定时器T0来产生周期不同的脉冲。首先,我们需要配置定时器T0为模式1,并设置适当的计数初值以得到所需的脉冲周期。以下是步骤及相应的程序代码:
1. **配置定时器T0**:
- 开启外部中断INT0(P3.2),作为定时器溢出中断源。
- 设置T0工作于模式1,即用内部时钟分频。
```c
TMOD = 0x01; // T0工作于模式1,TH0和TL0均为8位计数器
TR0 = 1; // 启动定时器T0
```
2. **计算计数初值**:
根据给定的频率(fosc = 12 MHz)和所需周期,计算每个引脚对应的计数值。假设单片机的定时器最大计数值为256(对于8位计数器)。
- P1.0:500 μs = 0.5 ms * 1000 μs/ms,计数次数约为249,取255(最大值减1)。
- P1.1:1 ms,计数次数为255。
- P1.2:5 ms,计数次数为510。
- P1.3:10 ms,计数次数为1020。
3. **编写中断服务函数(ISR)**:
- 对于每个引脚,当定时器溢出时,先停止T0,然后复位定时器并设置相应延时的输出。
```c
void timer0_isr(void) interrupt 1 {
TH0 = 0;
TL0 = 0; // 重置定时器
if (P1_0_flag) { // 检查P1.0状态
P1_0_flag = 0;
P1_0 = 1; // 输出高电平
__delay_ms(5); // 5ms延时
P1_0 = 0; // 输出低电平
}
if (P1_1_flag) { // ...类似处理其他引脚
... ...
}
}
// 初始化标志变量
unsigned char P1_0_flag = 0, P1_1_flag = 0, P1_2_flag = 0, P1_3_flag = 0;
// 在主循环中设置标志
while (1) {
if (!P1_0_flag) { // 当500us到达,设置标志并启动定时器
P1_0_flag = 1;
TR0 = 1;
}
// 类似地,对其他引脚做同样的操作
}
```
4. **外部中断初始化**:
- 配置INT0中断为下降沿触发,并开启中断请求。
```c
EIEH = 0b10000000; // 打开所有中断源,包括INT0
EX0 = 1; // 开启EXTI0(INT0)
EA = 1; // 全局中断使能
```
以上代码仅作示例,实际应用需要确保中断响应正确,并将标志变量与硬件连接。在编写完整程序时,请注意将`P1_0_flag`等替换为你实际的IO口控制寄存器名。
阅读全文