LeetCode ImplementStrstr
class Solution {
public:
char *strStr(char *haystack, char *needle) {
if (haystack == NULL || needle == NULL) return NULL;
int wpos[];
char cur = ;
int len = ;
for (int i=; i < ; i++) wpos[i] = -;
for (int i=; (cur = needle[i]) != '\0'; i++, len++) wpos[cur] = i;
int p = , q = ;
while (true) {
while (haystack[p] != '\0'
&& needle[q] != '\0'
&& haystack[p] == needle[q]) p++, q++;
if ( needle[q] == '\0') {
return haystack + p - q;
}
if (haystack[p] == '\0') {
return NULL;
}
int npos = p - q + len;
int move = wpos[haystack[npos]];
q = ;
if (move < ) {
p++;
} else {
p = npos - move;
}
}
return NULL;
}
};
又写了次sunday算法,还是磕磕碰碰
第二轮 3.21
Implement strStr().
Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
kmp、sunday都想不起来了,直接暴力吧,超时,然后加上一些条件能过应该是testcase不好,否则还是应该能造成超时:
class Solution {
public:
int strStr(char *haystack, char *needle) {
if (haystack == NULL || needle == NULL) {
return -;
}
int hlen = strlen(haystack);
int nlen = strlen(needle);
if (nlen > hlen) {
return -;
}
int hi = ;
int ni = ;
while (hi < (hlen - nlen + )) {
int ti = hi;
ni = ;
// try to campare start from haystack[ti] & needle[ni] (ti=hi, ni=0)
while (needle[ni] != '\0' && haystack[ti] != '\0') {
if (needle[ni] == haystack[ti]) {
ni++, ti++;
} else {
break;
}
}
if (needle[ni] == '\0') {
return hi;
}
// start from next char
hi++;
}
// not found
return -;
}
};
下面就超时:
class Solution {
public:
int strStr(char *haystack, char *needle) {
if (haystack == NULL || needle == NULL) {
return -;
}
for (int i=; true; i++) {
int ci = i;
int ni;
for(ni = ; needle[ni] && haystack[ci]; ni++, ci++) {
if (needle[ni] != haystack[ci]) {
break;
}
}
if (needle[ni] == '\0') {
return i;
}
if (haystack[i] == '\0') {
break;
}
}
// not found
return -;
}
};
下面又不超时,到底是为什么?不是一样的方式么
class Solution {
public:
int strStr(char *haystack, char *needle) {
int i,j;
for (i = j = ; haystack[i] && needle[j];) {
if (haystack[i] == needle[j]) {
++i;
++j;
} else {
i = i - j + ;
j = ;
}
}
return needle[j] ? - : (i - j);
}
};
一次Sunday算法:
#include <stdio.h>
#include <stdlib.h>
#include <string.h> int sunday(const char* src, const char* pattern) {
if (src == NULL || pattern == NULL) return -1;
int slen = strlen(src);
int plen = strlen(pattern); int cpos = ;
int dict[] = {};
memset(dict, -, sizeof(dict));
for (int i=; i<plen; i++) {
dict[pattern[i]] = i;
} while (cpos + plen <= slen) {
int i = ;
while (i < plen) {
if (src[i+cpos] != pattern[i]) {
break;
}
i++;
} if (i == plen) {
return cpos;
} int move = dict[src[cpos + plen]];
// printf("tail char: %c\n", pattern[cpos + plen]);
if (move < ) {
cpos = cpos + plen;
} else {
cpos = cpos + plen - move;
}
// printf("next pos:%d, %c\n", cpos, src[cpos]);
}
return -;
} int main(int argc, char* argv[]) { if (argc < ) {
printf("%s <src string> <pattern string>\n", argv[]);
return ;
} int idx = sunday(argv[], argv[]);
if (idx < ) {
printf("not found pattern in src string\n");
return ;
}
printf("match idx: %d, string from: %s\n", idx, argv[] + idx);
return ;
}
可以再简化代码:
#include <iostream>
#include <cstdlib> int sunday(const char* pattern, const char* str) {
if (pattern == NULL || str == NULL) {
return -;
}
int slen = , plen = ; while (pattern[plen] != '\0') plen++;
while (str[slen] != '\0') slen++; int tbl[];
for (int i=; i<; i++) tbl[i] = -;
for (int i=; i<plen; i++) tbl[pattern[i]] = i; int pi = , si = ; while (si < slen) {
while (str[si] == pattern[pi] && si < slen) si++, pi++;
if (pi == plen) return si - plen;
int nidx = plen - pi + si;
int offset = tbl[str[nidx]];
si = nidx - offset;
pi = ;
}
return -;
} int main() {
char* pattern = "simple";
char* str = "the example is a simple example."; int idx = sunday(pattern, str);
if (idx < ) {
printf("not found\n");
} else {
printf("found at: %d\n", idx);
printf("str:%s\n", str + idx);
}
system("pause");
return ;
}
si = nidx - offset;
这里当offset是负数时和非负数时其实是两种情况,但是因为将tbl数组初始化了为-1,所以nidx-offset其实相当于nidx + 1,刚刚可以把两种情况统一了。 感觉前面的暴力法写的复杂了,思路可以再清晰一些:
class Solution {
public:
int strStr(string haystack, string needle) {
int hlen = haystack.size();
int nlen = needle.size();
for (int i=; i<hlen; i++) {
int p = i, q = ;
if (hlen - i < nlen) {
return -;
}
while (p < hlen && q < nlen && haystack[p] == needle[q]) p++, q++;
if (q == nlen) {
return i;
}
}
return nlen == ? : -;
}
};
LeetCode ImplementStrstr的更多相关文章
- [LeetCode] Implement strStr() 实现strStr()函数
Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if needle ...
- leetcode算法分类
利用堆栈:http://oj.leetcode.com/problems/evaluate-reverse-polish-notation/http://oj.leetcode.com/problem ...
- LeetCode题目分类
利用堆栈:http://oj.leetcode.com/problems/evaluate-reverse-polish-notation/http://oj.leetcode.com/problem ...
- <转>LeetCode 题目总结/分类
原链接:http://blog.csdn.net/yangliuy/article/details/44514495 注:此分类仅供大概参考,没有精雕细琢.有不同意见欢迎评论~ 利用堆栈:http:/ ...
- [Leetcode][Python]28: Implement strStr()
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 28: Implement strStr()https://oj.leetco ...
- [LeetCode]题解(python):028-Implement strStr()
题目来源: https://leetcode.com/problems/implement-strstr/ 题意分析: 输入两个字符串haystack和needle,如果needle是haystack ...
- LeetCode 题目总结/分类
LeetCode 题目总结/分类 利用堆栈: http://oj.leetcode.com/problems/evaluate-reverse-polish-notation/ http://oj.l ...
- Leetcode 题解
Leetcode Solutions Language: javascript c mysql Last updated: 2019-01-04 https://github.com/nusr/lee ...
- LeetCode 28 Implement strStr() (实现找子串函数)
题目链接: https://leetcode.com/problems/implement-strstr/?tab=Description Problem : 实现找子串的操作:如果没有找到则返回 ...
随机推荐
- Unity 下集成第三方原生 SDK,以极光厂商通道为例
Unity中集成三方SDK有两种方式: Unity 项目开发中时常有集成 Android 第三方 SDK 的需求,比如接入第三方推送,分享等功能.而第三方 SDK 的集成文档提到的往往是基于原生 An ...
- 使用IDEA结合MAVEN创建一个Spring Java Web项目
前言 如今的Java项目,如果还使用传统的把jar包复制到目录下这种原始的方式,对于依赖管理来说实在是灾难.对某个功能需要引入某种技术包,但是你不确定是否已存在,如果分类好的话还好找,若是杂在一堆不仅 ...
- FlowPortal-BPM——离线审批(邮箱审批)配置
一.将系统文件复制到安装目录下 二.以管理员身份运行bat安装程序 三.开启邮件离线审批服务 四.创建数据库表(JAVA数据库 或 .Net数据库) 五.配置config文件(发件箱.收件箱.错误问题 ...
- 前端知识总结--js原型链
js的原型链听着比较深奥,看着容易晕,梳理一下还是比较容易懂的 (先简单写下,后续有时间再整理) 简而言之 原型链:就是js的对象与对象之间,通过原型组成建立的层层关系,构成了整个链条,称之为原型链 ...
- Mac下截图工具
苹果系统自带截图功能 1.截取全屏:快捷键(Shift+Command+3) ▲直接按“Shift+Command+3“快捷键组合,即可截取电脑全屏,图片自动保存在桌面. 2.截图窗口:快捷键(Shi ...
- vue中的双向数据绑定详解
前言 什么是数据双向绑定? vue是一个mvvm框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化.这也算是vue的精髓之处了.值得注意的是,我 ...
- Thinkphp3.2.X自动生成应用目录
从3.2.2版本开始,可以支持自动生成默认模块之外的模块目录以及批量生成控制器和模型类. 例如,如果我们需要生成一个Admin模块用于后台应用,在应用入口文件中定义如下: // 绑定Admin模块到当 ...
- hibernate配置hbm2ddl.auto的四个参数
<!-- Drop and re-create the database schema on startup --> <!-- hbm(hibernatemapping) ,ddl( ...
- 爱奇艺视频显示列表CSS实现
css: body{margin:0;font-size: 12px;font-family: "宋体":} ul{margin:0;padding:0;list-style: n ...
- 《Algorithms算法》笔记:元素排序(4)——凸包问题
<Algorithms算法>笔记:元素排序(4)——凸包问题 Algorithms算法笔记元素排序4凸包问题 凸包问题 凸包问题的应用 凸包的几何性质 Graham 扫描算法 代码 凸包问 ...