LeetCode Online Judge 题目C# 练习 - Implement strStr()

Implement strStr().
Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.

needle in the haystack 大海捞针的意思

其实就是找出 “短字符串” 在 “长字符串” 中的位置。

 1 public static string strStr(string haystack, string needle)
 2         {
 3             if (haystack.Length == 0)
 4                 return string.Empty;
 5             if (needle.Length == 0)
 6                 return string.Empty;
 7             if (needle.Length > haystack.Length)
 8                 return string.Empty;
 9 
10             for (int i = 0; i < haystack.Length; i++)
11             {
12                 bool found = true;
13                 for (int j = 0; j < needle.Length; j++)
14                 {
15                     if (haystack[i + j] != needle[j])
16                     {
17                         found = false;
18                         break;
19                     }
20                 }
21                 if(found)
22                     return haystack.Substring(i);
23             }
24 
25             return string.Empty;
26         }

代码分析:

  第一时间想到的应该是这个两重循环的方法,O(n2)。

 1 public static string strStrOpt(string haystack, string needle)
 2         {
 3             if (haystack.Length == 0)
 4                 return string.Empty;
 5             if (needle.Length == 0)
 6                 return string.Empty;
 7             if (needle.Length > haystack.Length)
 8                 return string.Empty;
 9 
10             //Create a partial match table
11             int[] table = new int[needle.Length];
12             partial_table(needle, table);
13 
14             // Search
15             int h_index = 0;
16             int n_index = 0;
17 
18             while (h_index + n_index < haystack.Length)
19             {
20                 if (needle[n_index] == haystack[h_index + n_index])
21                 {
22                     if (n_index == needle.Length - 1)
23                         return haystack.Substring(h_index);
24                     else
25                         ++n_index;
26                 }
27                 else
28                 {
29                     h_index = h_index + n_index - table[n_index];
30                     if (table[n_index] > -1)
31                         n_index = table[n_index];
32                     else
33                         n_index = 0;
34                 }
35             }
36 
37             return string.Empty;
38         }
39 
40         public static void partial_table(string word, int[] table)
41         {
42             if (0 == table.Length)
43                 return;
44 
45             if (1 == table.Length)
46             {
47                 table[0] = -1;
48                 return;
49             }
50 
51             table[0] = -1;
52             table[1] = 0;
53 
54             int pos = 2;
55             int cnd = 0;
56 
57             while (pos < table.Length)
58             {
59                 if (word[pos - 1] == word[cnd])
60                     table[pos++] = ++cnd;
61                 else if (cnd > 0)
62                     cnd = table[cnd];
63                 else
64                     table[pos++] = 0;
65             }
66         }

代码分析:

  为了提高效率,我们希望直接跳到needle长度后一个字符来比较。比如说。

  “ABDABDABC”中找“ABC"。如果对比完第一个"ABD"发现不相等,我们希望跳到下一个"A"开始,而不是从字符串中第二个字符"B"开始。

  但是如果needle字符串中带有重复的。比如 "ABABACAB" 中找 “ABAC" 比较完 "ABAB" != "ABAC"以后,不能跳到第3个"A"开始比较,因为needle中有重复的,这样会错过了从第二个”A"开始的“ABAC".

  所以,以上代码使用了一个array来 看needle字符串中重复位置。

  ”ABAC" 会生成ARRAY [ -1,0,0,1], 当比较到"B" != "C", h_index = h_index + n_index - table[n_index], 从第2个“A”开始再比较。

posted @ 2012-09-07 05:47  ETCOW  阅读(1420)  评论(2编辑  收藏  举报