概要
cscの作法、調べてみた。
grep見つけたので、やってみた。
参考にしたページ
サンプルコード
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
public class Searcher {
protected readonly string[] Words;
public Searcher(string[] words) {
Words = words;
}
public virtual bool Search(string line) {
return Words.Any(x => line.Contains(x));
}
}
public class RegexSearcher: Searcher {
private readonly Regex pattern;
public RegexSearcher(string[] words): base(words) {
Array.Sort(words);
var p = string.Join("|", words.Select(Regex.Escape));
pattern = new Regex(p, RegexOptions.Compiled);
}
public override bool Search(string line) {
return pattern.IsMatch(line);
}
}
public class KmpSearcher: Searcher {
private readonly Kmp[] matchers;
public KmpSearcher(string[] words): base(words) {
matchers = words.Select(x => new Kmp(x)).ToArray();
}
public override bool Search(string line) {
foreach (var m in matchers)
m.Reset();
return line.Any(c => matchers.Any(m => m.Match(c)));
}
private class Kmp {
private string pattern;
private int[] table;
private int matchingLength = 0;
public Kmp(string p) {
pattern = p;
table = new int[p.Length];
if (p.Length < 1)
return;
table[0] = -1;
if (p.Length < 2)
return;
table[1] = 0;
int i = 2;
int length = 0;
while (i < p.Length)
{
if (p[i - 1] == p[length])
{
length++;
table[i] = length;
i++;
}
else if (length > 0)
{
length = table[length];
}
else
{
table[i] = 0;
i++;
}
}
}
public bool Match(char c) {
if (pattern.Length <= matchingLength)
{
return true;
}
while (pattern[matchingLength] != c)
{
matchingLength = table[matchingLength];
if (matchingLength < 0)
{
matchingLength = 0;
return false;
}
}
matchingLength++;
return (pattern.Length <= matchingLength);
}
public void Reset() {
matchingLength = 0;
}
}
}
public static class GrepUtil {
public static Func<string[], Searcher> SearcherFactory = words => new Searcher(words);
public static IEnumerable<String> Grep(TextReader reader, params string[] words) {
var searcher = SearcherFactory(words);
string line;
for (var i = 1; (line = reader.ReadLine()) != null; i++)
if (searcher.Search(line))
yield return i + ": " + line;
}
}
public class Program {
public static void Main(string[] args) {
string input = @"Java 1 is nice.
Java 2 is fine.
Java 3 is good.
Java 4 is good.
Java 5 is fine.
Java 6 is good.
Java 7 is good.
Java 8 is marvelous.";
using (var sr = new StringReader(input))
{
List<string> result = GrepUtil.Grep(sr, "fine", "marvelous").ToList();
foreach (var item in result)
Console.WriteLine(item);
}
}
}
実行結果
>grep0
2: Java 2 is fine.
5: Java 5 is fine.
8: Java 8 is marvelous.
以上。