Skip to content

Commit c171850

Browse files
author
tianqing.liang
committed
字符串匹配
1 parent 7acb29b commit c171850

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+30015
-1042
lines changed

23-MSDSort-And-BucketSort/SortingHelper.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class SortingHelper {
99
return true;
1010
}
1111

12-
static sortTest(String sortname, List? arr) {
12+
static sortTest(String sortname, List arr) {
1313
var now = new DateTime.now();
1414
num startTime = now.millisecondsSinceEpoch;
1515

24-SubString-Match/FileOperator.dart

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import 'dart:io';
2+
import 'dart:convert';
3+
4+
/**
5+
* 文件操作类
6+
*/
7+
class FileOperator{
8+
9+
static Future<List> getFileString(String filename) async{
10+
Stream<List<int>> content = File(filename).openRead();
11+
List<String> lines = await content.transform(utf8.decoder).transform(LineSplitter()).toList();
12+
var words = [];
13+
for(int i = 0;i<lines.length;i++){
14+
words.addAll(lines[i].split(" ").toList());
15+
}
16+
words.removeWhere((element) => element == "");
17+
return words;
18+
}
19+
}

24-SubString-Match/LC1392-hash.dart

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
class Solution2 {
2+
double MOD = 1e9 + 7;
3+
4+
String longestPrefix(String s) {
5+
List<int> pow26 = List.filled(s.length, 0, growable: true);
6+
pow26[0] = 1;
7+
for (int i = 1; i < pow26.length; i++)
8+
pow26[i] = (pow26[i - 1] * 26 % MOD).toInt();
9+
10+
// prehash[i]: hash(s[0...i])
11+
List<int> prehash = List.filled(s.length, 0, growable: true);
12+
prehash[0] = s[0].codeUnits[0] - 'a'.codeUnits[0];
13+
for (int i = 1; i < s.length; i++)
14+
prehash[i] =
15+
((prehash[i - 1] * 26 + s[i].codeUnits[0] - 'a'.codeUnits[0]) % MOD)
16+
.toInt();
17+
18+
// posthash[i]: hash(s[i...s.length - 1])
19+
List<int> posthash = List.filled(s.length, 0, growable: true);
20+
posthash[s.length - 1] = s[s.length - 1].codeUnits[0] - 'a'.codeUnits[0];
21+
for (int i = s.length - 2; i >= 0; i--)
22+
posthash[i] =
23+
((pow26[s.length - i - 1] * (s[i].codeUnits[0] - 'a'.codeUnits[0]) +
24+
posthash[i + 1]) %
25+
MOD)
26+
.toInt();
27+
28+
// s[0...len - 1], s[s.length - len...s.length - 1]
29+
for (int len = s.length - 1; len >= 1; len--) {
30+
if (prehash[len - 1] == posthash[s.length - len] &&
31+
_equal(s, 0, len - 1, s.length - len, s.length - 1))
32+
return s.substring(0, len);
33+
}
34+
return "";
35+
}
36+
37+
bool _equal(String s, int l1, int r1, int l2, int r2) {
38+
for (int i = l1, j = l2; i <= r1 && j <= r2; i++, j++)
39+
if (s[i] != s[j]) return false;
40+
return true;
41+
}
42+
}

24-SubString-Match/LC1392.dart

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
class Solution {
2+
3+
String longestPrefix(String s) {
4+
5+
// s[0...len - 1], s[s.length - len...s.length - 1]
6+
for(int len = s.length - 1; len >= 1; len --)
7+
if(_equal(s, 0, len - 1, s.length - len, s.length - 1))
8+
return s.substring(0, len);
9+
return "";
10+
}
11+
12+
bool _equal(String s, int l1, int r1, int l2, int r2){
13+
14+
for(int i = l1, j = l2; i <= r1 && j <= r2; i ++, j ++)
15+
if(s[i] != s[j]) return false;
16+
return true;
17+
}
18+
19+
20+
}
21+
22+
void main() {
23+
24+
print((new Solution()).longestPrefix("level"));
25+
}
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import 'dart:collection';
2+
class Solution2 {
3+
List<String> findRepeatedDnaSequences(String s) {
4+
5+
if(s.length < 10) {
6+
return List.empty(growable: true);
7+
};
8+
9+
List<int> map = List.filled(256,0, growable: true);
10+
map['A'.codeUnits[0]] = 1;
11+
map['C'.codeUnits[0]] = 2;
12+
map['G'.codeUnits[0]] = 3;
13+
map['T'.codeUnits[0]] = 4;
14+
15+
HashSet<int> seen = new HashSet<int>();
16+
HashSet<String> res = new HashSet<String>();
17+
18+
int hash = 0;
19+
double ten9 = 1e9;
20+
21+
for(int i = 0; i < 9; i ++)
22+
hash = hash * 10 + map[s[i].codeUnits[0]];
23+
24+
for(int i = 9; i < s.length; i ++){
25+
26+
hash = hash * 10 + map[s[i].codeUnits[0]];
27+
28+
if(seen.contains(hash)) res.add(s.substring(i - 9, i + 1));
29+
else seen.add(hash);
30+
31+
hash -= (map[s[i - 9].codeUnits[0]] * ten9).toInt();
32+
}
33+
return res.toList();
34+
}
35+
}

24-SubString-Match/LC187.dart

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import 'dart:collection';
2+
class Solution {
3+
List<String> findRepeatedDnaSequences(String s) {
4+
5+
HashSet<String> seen = HashSet<String>();
6+
HashSet<String> res = HashSet<String>();
7+
for(int i = 0; i + 10 <= s.length; i ++){
8+
String key = s.substring(i, i + 10);
9+
if(seen.contains(key))
10+
res.add(key);
11+
else
12+
seen.add(key);
13+
}
14+
return res.toList();
15+
}
16+
}

24-SubString-Match/Solution.dart

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* 1147号问题使用遍历查询
3+
*/
4+
class Solution {
5+
int longestDecomposition(String text) {
6+
return _solve(text, 0, text.length - 1);
7+
}
8+
9+
int _solve(String s, int left, int right) {
10+
if (left > right) return 0;
11+
12+
for (int i = left, j = right; i < j; i++, j--) {
13+
if (_equal(s, left, i, j, right)) return 2 + _solve(s, i + 1, j - 1);
14+
}
15+
return 1;
16+
}
17+
18+
bool _equal(String s, int l1, int r1, int l2, int r2) {
19+
for (int i = l1, j = l2; i <= r1 && j <= r2; i++, j++)
20+
if (s[i] != s[j]) return false;
21+
return true;
22+
}
23+
}

24-SubString-Match/Solution2.dart

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* 1147号问题使用hash值解决
3+
*/
4+
class Solution2 {
5+
double MOD = 1e9 + 7;
6+
7+
List<double>? pow26;
8+
9+
int longestDecomposition(String text) {
10+
pow26 = List.filled(text.length, 0, growable: true);
11+
pow26![0] = 1;
12+
for (int i = 1; i < pow26!.length; i++)
13+
pow26![i] = pow26![i - 1] * 26 % MOD;
14+
15+
return _solve(text, 0, text.length - 1);
16+
}
17+
18+
int _solve(String s, int left, int right) {
19+
if (left > right) return 0;
20+
21+
int prehash = 0, posthash = 0;
22+
for (int i = left, j = right; i < j; i++, j--) {
23+
prehash = ((prehash * 26 + (s[i].codeUnits[0] - 'a'.codeUnits[0])) % MOD)
24+
.toInt();
25+
posthash = (((s[j].codeUnits[0] - 'a'.codeUnits[0]) * pow26![right - j] +
26+
posthash) %
27+
MOD)
28+
.toInt();
29+
30+
if (prehash == posthash && _equal(s, left, i, j, right))
31+
return 2 + _solve(s, i + 1, j - 1);
32+
}
33+
return 1;
34+
}
35+
36+
bool _equal(String s, int l1, int r1, int l2, int r2) {
37+
for (int i = l1, j = l2; i <= r1 && j <= r2; i++, j++)
38+
if (s[i] != s[j]) return false;
39+
return true;
40+
}
41+
}
+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import 'SubstringMatchHelper.dart';
2+
import 'FileOperator.dart';
3+
4+
/**
5+
* 字符串匹配
6+
*/
7+
class SubstringMatch {
8+
//粗暴强制
9+
static int bruteforce(String s, String t) {
10+
if (s.length < t.length) return -1;
11+
// s[i, i + t.length - 1]
12+
for (int i = 0; i + t.length - 1 < s.length; i++) {
13+
int j = 0;
14+
for (; j < t.length; j++)
15+
if (s[i + j] != t[j]) break;
16+
if (j == t.length) return i;
17+
}
18+
return -1;
19+
}
20+
21+
static int rabinKarp(String s, String t) {
22+
if (s.length < t.length) return -1;
23+
if (t.length == 0) return 0;
24+
25+
int thash = 0,
26+
B = 256;
27+
double MOD = 1e9 + 7;
28+
for(int i = 0; i < t.length; i ++){
29+
thash = ((thash * B + t[i].codeUnits[0]) % MOD).toInt();
30+
};
31+
int hash = 0, P = 1;
32+
for(int i = 0; i < t.length - 1; i ++)
33+
P = (P * B % MOD).toInt();
34+
35+
for(int i = 0; i < t.length - 1; i ++)
36+
hash = ((hash * B + s[i].codeUnits[0]) % MOD).toInt();
37+
38+
for(int i = t.length- 1; i < s.length; i ++){
39+
hash = ((hash * B + s[i].codeUnits[0]) % MOD).toInt();
40+
if(hash == thash && _equal(s, i - t.length + 1, t))
41+
return i - t.length + 1;
42+
hash = ((hash - s[i - t.length + 1].codeUnits[0] * P % MOD + MOD) % MOD).toInt();
43+
}
44+
return
45+
-
46+
1;
47+
}
48+
49+
static bool _equal(String s, int l, String t) {
50+
for (int i = 0; i < t.length; i ++)
51+
if (s[l].codeUnits[0] + i != t[i].codeUnits[0]) return false;
52+
return true;
53+
}
54+
}
55+
56+
void main() async {
57+
String s1 = "hello, this is liuyubobobo.";
58+
String t1 = "bo";
59+
SubstringMatchHelper.matchTest("bruteforce", s1, t1);
60+
61+
List s2 = await FileOperator.getFileString("text2.txt");
62+
String t2 = "china";
63+
StringBuffer res = new StringBuffer();
64+
for (int i = 0; i < s2.length; i++) {
65+
res.write(s2[i]);
66+
}
67+
68+
SubstringMatchHelper.matchTest("bruteforce", res.toString(), t2);
69+
70+
SubstringMatchHelper.matchTest("bruteforce", res.toString(), "zyx");
71+
72+
/// Worst case
73+
int n = 1000000,
74+
m = 1000;
75+
76+
StringBuffer s3 = new StringBuffer();
77+
for (int i = 0; i < n; i++)
78+
s3.write('a');
79+
80+
StringBuffer t3 = new StringBuffer();
81+
for (int i = 0; i < m - 1; i++)
82+
t3.write('a');
83+
t3.write('b');
84+
85+
SubstringMatchHelper.matchTest("bruteforce", s3.toString(), t3.toString());
86+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import 'SubstringMatch.dart';
2+
class SubstringMatchHelper {
3+
4+
SubstringMatchHelper(){}
5+
6+
static void matchTest(String name, String s, String t){
7+
8+
int pos = -1;
9+
10+
int startTime = new DateTime.now().millisecondsSinceEpoch;
11+
if(name == "bruteforce"){
12+
pos = SubstringMatch.bruteforce(s, t);
13+
}
14+
int endTime = new DateTime.now().millisecondsSinceEpoch;
15+
16+
double time = (endTime - startTime) / 1000.0;
17+
18+
print(startTime);
19+
print(endTime);
20+
if(s.indexOf(t) != pos)
21+
throw new Exception(name + " failed");
22+
print("$name : res = $pos, time = $time s");
23+
}
24+
25+
}

0 commit comments

Comments
 (0)