Created
April 11, 2016 04:55
-
-
Save jianminchen/43e8593146434339285a87dc38fae166 to your computer and use it in GitHub Desktop.
string function calculation - HackerRank - using Boyer Moore algorithm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace stringFunctionCalculation | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
string s = Console.ReadLine(); | |
Console.WriteLine(getMaximumValue(s).ToString()); | |
} | |
public static int getMaximumValue(string s) | |
{ | |
if (s == null || s.Length == 0) return 0; | |
int n = s.Length; | |
int pValue = 1; | |
HashSet<string> set = new HashSet<string>(); | |
for (int i = 1; i <= n; i++) // substring length: i bug01: should be i<= n, not i< n | |
{ | |
int start = 0; | |
int end = i - 1; | |
while (start <= n - 1 && end <= n - 1) | |
{ | |
string s1 = s.Substring(0, i); | |
if (!set.Contains(s1)) // check if set has string | |
{ | |
set.Add(s1); | |
int current = i * getCountSubstringUsingBoyerAlgo(s1, s); | |
if (current > pValue) | |
pValue = current; | |
} | |
start++; | |
end++; | |
} | |
} | |
return pValue; | |
} | |
/* | |
* using Boyer Algorithm | |
*/ | |
private static int getCountSubstringUsingBoyerAlgo(string substring, string s) | |
{ | |
int len1 = substring.Length; | |
int len = s.Length; | |
if (len1 > len) return 0; | |
BoyerMoore bm = new BoyerMoore(substring); | |
string newstring = s; | |
int count = 0; | |
//while (newstring != null && newstring.Length > len1) // bug002 newstring.Length >= len1 | |
while (newstring != null && newstring.Length >= len1) | |
{ | |
int offset = bm.search(newstring); | |
if (offset < newstring.Length) | |
{ | |
count++; | |
//newstring = newstring.Substring(offset + len1); // bug001 - offset + len1 should be offset+1 | |
newstring = newstring.Substring(offset + 1); | |
} | |
else | |
break; | |
} | |
return count; | |
} | |
} | |
public class BoyerMoore { | |
private int R; // the radix | |
private int[] right; // the bad-character skip array | |
private char[] pattern; // store the pattern as a character array | |
private String pat; // or as a string | |
/** | |
* | |
* code source from Java code | |
* | |
* http://algs4.cs.princeton.edu/53substring/BoyerMoore.java.html | |
* Preprocesses the pattern string. | |
* | |
* @param pat the pattern string | |
*/ | |
public BoyerMoore(String pat) { | |
this.R = 256; | |
this.pat = pat; | |
// position of rightmost occurrence of c in the pattern | |
right = new int[R]; | |
for (int c = 0; c < R; c++) | |
right[c] = -1; | |
for (int j = 0; j < pat.Length; j++) | |
right[pat[j]] = j; | |
} | |
/** | |
* Preprocesses the pattern string. | |
* | |
* @param pattern the pattern string | |
* @param R the alphabet size | |
*/ | |
public BoyerMoore(char[] pattern, int R) { | |
this.R = R; | |
this.pattern = new char[pattern.Length]; | |
for (int j = 0; j < pattern.Length; j++) | |
this.pattern[j] = pattern[j]; | |
// position of rightmost occurrence of c in the pattern | |
right = new int[R]; | |
for (int c = 0; c < R; c++) | |
right[c] = -1; | |
for (int j = 0; j < pattern.Length; j++) | |
right[pattern[j]] = j; | |
} | |
/** | |
* Returns the index of the first occurrrence of the pattern string | |
* in the text string. | |
* | |
* @param txt the text string | |
* @return the index of the first occurrence of the pattern string | |
* in the text string; N if no such match | |
*/ | |
public int search(String txt) { | |
int M = pat.Length; | |
int N = txt.Length; | |
int skip; | |
for (int i = 0; i <= N - M; i += skip) { | |
skip = 0; | |
for (int j = M-1; j >= 0; j--) { | |
if (pat[j] != txt[i+j]) { | |
skip = Math.Max(1, j - right[txt[i+j]]); | |
break; | |
} | |
} | |
if (skip == 0) return i; // found | |
} | |
return N; // not found | |
} | |
/** | |
* Returns the index of the first occurrrence of the pattern string | |
* in the text string. | |
* | |
* @param text the text string | |
* @return the index of the first occurrence of the pattern string | |
* in the text string; N if no such match | |
*/ | |
public int search(char[] text) { | |
int M = pattern.Length; | |
int N = text.Length; | |
int skip; | |
for (int i = 0; i <= N - M; i += skip) { | |
skip = 0; | |
for (int j = M-1; j >= 0; j--) { | |
if (pattern[j] != text[i+j]) { | |
skip = Math.Max(1, j - right[text[i+j]]); | |
break; | |
} | |
} | |
if (skip == 0) return i; // found | |
} | |
return N; // not found | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment