批量字符串替换程序
很多时候我们需要用到字符串替换程序,比如插入数据库时需要将'替换成''。当只有少数待换字符串时用String.Replace性能很高,但因为其复杂度是O(n),当待换字符串很多的时候,String.Replace的性能就降下来了。前些天写了几个程序,用于批量替换字符串。
问题:批量替换字符串。定义字符串对PairString{OldValue,NewValue}。
OldValue<------>NewValue
称---->为右过滤,简称过滤。<----为左过滤,或反过滤。
给定字符串S,一个PairString数组,用PairString数组过滤S(左、右可设置)。
程序实现:
(1)PairString
(2)采用Replace实现
(3)批量替换。我最先采用Hashtable实现,测试结果发现性能比较低,然后就直接改用数组实现,写一个hash函数,将待换字符串hash到数组。flexIndex是松弛系数。
(4)例子
一般来说,如果待换字符串在10个以下,使用Replace性能较高。10个以上的,批量替换的优势就体现出来了。
问题:批量替换字符串。定义字符串对PairString{OldValue,NewValue}。
OldValue<------>NewValue
称---->为右过滤,简称过滤。<----为左过滤,或反过滤。
给定字符串S,一个PairString数组,用PairString数组过滤S(左、右可设置)。
程序实现:
(1)PairString
1 public struct PairString
2 {
3 public string OldValue;
4 public string NewValue;
5 public bool IsRightFilter;
6 public bool IsLeftFilter;
7
8 public PairString(string oldValue, string newValue)
9 {
10 OldValue=oldValue;
11 NewValue=newValue;
12 IsRightFilter=true;
13 IsLeftFilter=true;
14 }
15
16 public PairString(string oldValue, string newValue, bool isRightFilter, bool isLeftFilter)
17 {
18 OldValue=oldValue;
19 NewValue=newValue;
20 IsRightFilter=isRightFilter;
21 IsLeftFilter=isLeftFilter;
22 }
23 }
2 {
3 public string OldValue;
4 public string NewValue;
5 public bool IsRightFilter;
6 public bool IsLeftFilter;
7
8 public PairString(string oldValue, string newValue)
9 {
10 OldValue=oldValue;
11 NewValue=newValue;
12 IsRightFilter=true;
13 IsLeftFilter=true;
14 }
15
16 public PairString(string oldValue, string newValue, bool isRightFilter, bool isLeftFilter)
17 {
18 OldValue=oldValue;
19 NewValue=newValue;
20 IsRightFilter=isRightFilter;
21 IsLeftFilter=isLeftFilter;
22 }
23 }
(2)采用Replace实现
1 public class StringFilter
2 {
3 private PairString[] _filterSet=null;
4
5 public PairString[] FilterSet
6 {
7 get
8 {
9 return _filterSet;
10 }
11 set
12 {
13 _filterSet=value;
14 }
15 }
16
17
18 public StringFilter()
19 {
20 }
21
22
23 public virtual string Filter(string input)
24 {
25 foreach (PairString p in FilterSet)
26 {
27 if(p.IsRightFilter==true) input=input.Replace(p.OldValue,p.NewValue);
28 }
29 return input;
30 }
31
32 public virtual string AntiFilter(string input)
33 {
34 foreach (PairString p in FilterSet)
35 {
36 if(p.IsLeftFilter==true) input=input.Replace(p.NewValue,p.OldValue);
37 }
38 return input;
39 }
40 }
2 {
3 private PairString[] _filterSet=null;
4
5 public PairString[] FilterSet
6 {
7 get
8 {
9 return _filterSet;
10 }
11 set
12 {
13 _filterSet=value;
14 }
15 }
16
17
18 public StringFilter()
19 {
20 }
21
22
23 public virtual string Filter(string input)
24 {
25 foreach (PairString p in FilterSet)
26 {
27 if(p.IsRightFilter==true) input=input.Replace(p.OldValue,p.NewValue);
28 }
29 return input;
30 }
31
32 public virtual string AntiFilter(string input)
33 {
34 foreach (PairString p in FilterSet)
35 {
36 if(p.IsLeftFilter==true) input=input.Replace(p.NewValue,p.OldValue);
37 }
38 return input;
39 }
40 }
(3)批量替换。我最先采用Hashtable实现,测试结果发现性能比较低,然后就直接改用数组实现,写一个hash函数,将待换字符串hash到数组。flexIndex是松弛系数。
1 public class StringBatchFilter:StringFilter
2 {
3 private int width=0;
4 const int flexIndex = 10;
5
6 private object[] _rightArray;
7 private object[] _leftArray;
8
9 public object[] RightArray
10 {
11 get
12 {
13 return _rightArray;
14 }
15 set
16 {
17 _rightArray = value;
18 }
19 }
20
21 public object[] LeftArray
22 {
23 get
24 {
25 return _leftArray;
26 }
27 set
28 {
29 _leftArray = value;
30 }
31 }
32
33 public StringBatchFilter()
34 {
35 }
36
37 public void Init()
38 {
39 width=flexIndex*FilterSet.Length;
40 RightArray = new object[width];
41 LeftArray = new object[width];
42
43 foreach (PairString p in FilterSet)
44 {
45 if(p.IsRightFilter==true)
46 {
47 if(RightArray[p.OldValue[0]%width]==null)
48 {
49 RightArray[p.OldValue[0]%width]=new ArrayList();
50 }
51 ((ArrayList)RightArray[p.OldValue[0]%width]).Add(p);
52
53 }
54
55 if(p.IsLeftFilter==true)
56 {
57 if(LeftArray[p.NewValue[0]%width]==null)
58 {
59 LeftArray[p.NewValue[0]%width]=new ArrayList();
60 }
61 else
62 {
63 ((ArrayList)LeftArray[p.NewValue[0]%width]).Add(p);
64 }
65 }
66 }
67 }
68
69 public override string Filter(string input)
70 {
71 StringBuilder sb = new StringBuilder((int)(input.Length*1.2));
72
73 for (int i=0; i< input.Length; )
74 {
75 int m = input[i]%width;
76 ArrayList l = (ArrayList)RightArray[m];
77 if(l!=null)
78 {
79 for(int j=0;j<l.Count;j++)
80 {
81 PairString p = (PairString)l[j];
82 if(((i+p.OldValue.Length)<input.Length))
83 {
84 if(input.Substring(i,p.OldValue.Length)==p.OldValue)
85 {
86 sb.Append(p.NewValue);
87 i+=p.OldValue.Length;
88 goto label;
89 }
90 }
91 }
92 sb.Append(input[i]);
93 i++;
94 label:
95 ;
96 }
97 else
98 {
99 sb.Append(input[i]);
100 i++;
101 }
102 }
103 return sb.ToString();
104 }
105
106 public override string AntiFilter(string input)
107 {
108 StringBuilder sb = new StringBuilder((int)(input.Length*1.2));
109
110 for (int i=0; i< input.Length; )
111 {
112 int m = input[i]%width;
113 ArrayList l = (ArrayList)LeftArray[m];
114 if(l!=null)
115 {
116 for(int j=0;j<l.Count;j++)
117 {
118 PairString p = (PairString)l[j];
119 if(((i+p.NewValue.Length)<input.Length))
120 {
121 if(input.Substring(i,p.NewValue.Length)==p.NewValue)
122 {
123 sb.Append(p.OldValue);
124 i+=p.NewValue.Length;
125 goto label;
126 }
127 }
128 }
129 sb.Append(input[i]);
130 i++;
131 label:
132 ;
133 }
134 else
135 {
136 sb.Append(input[i]);
137 i++;
138 }
139 }
140 return sb.ToString();
141 }
142 }
2 {
3 private int width=0;
4 const int flexIndex = 10;
5
6 private object[] _rightArray;
7 private object[] _leftArray;
8
9 public object[] RightArray
10 {
11 get
12 {
13 return _rightArray;
14 }
15 set
16 {
17 _rightArray = value;
18 }
19 }
20
21 public object[] LeftArray
22 {
23 get
24 {
25 return _leftArray;
26 }
27 set
28 {
29 _leftArray = value;
30 }
31 }
32
33 public StringBatchFilter()
34 {
35 }
36
37 public void Init()
38 {
39 width=flexIndex*FilterSet.Length;
40 RightArray = new object[width];
41 LeftArray = new object[width];
42
43 foreach (PairString p in FilterSet)
44 {
45 if(p.IsRightFilter==true)
46 {
47 if(RightArray[p.OldValue[0]%width]==null)
48 {
49 RightArray[p.OldValue[0]%width]=new ArrayList();
50 }
51 ((ArrayList)RightArray[p.OldValue[0]%width]).Add(p);
52
53 }
54
55 if(p.IsLeftFilter==true)
56 {
57 if(LeftArray[p.NewValue[0]%width]==null)
58 {
59 LeftArray[p.NewValue[0]%width]=new ArrayList();
60 }
61 else
62 {
63 ((ArrayList)LeftArray[p.NewValue[0]%width]).Add(p);
64 }
65 }
66 }
67 }
68
69 public override string Filter(string input)
70 {
71 StringBuilder sb = new StringBuilder((int)(input.Length*1.2));
72
73 for (int i=0; i< input.Length; )
74 {
75 int m = input[i]%width;
76 ArrayList l = (ArrayList)RightArray[m];
77 if(l!=null)
78 {
79 for(int j=0;j<l.Count;j++)
80 {
81 PairString p = (PairString)l[j];
82 if(((i+p.OldValue.Length)<input.Length))
83 {
84 if(input.Substring(i,p.OldValue.Length)==p.OldValue)
85 {
86 sb.Append(p.NewValue);
87 i+=p.OldValue.Length;
88 goto label;
89 }
90 }
91 }
92 sb.Append(input[i]);
93 i++;
94 label:
95 ;
96 }
97 else
98 {
99 sb.Append(input[i]);
100 i++;
101 }
102 }
103 return sb.ToString();
104 }
105
106 public override string AntiFilter(string input)
107 {
108 StringBuilder sb = new StringBuilder((int)(input.Length*1.2));
109
110 for (int i=0; i< input.Length; )
111 {
112 int m = input[i]%width;
113 ArrayList l = (ArrayList)LeftArray[m];
114 if(l!=null)
115 {
116 for(int j=0;j<l.Count;j++)
117 {
118 PairString p = (PairString)l[j];
119 if(((i+p.NewValue.Length)<input.Length))
120 {
121 if(input.Substring(i,p.NewValue.Length)==p.NewValue)
122 {
123 sb.Append(p.OldValue);
124 i+=p.NewValue.Length;
125 goto label;
126 }
127 }
128 }
129 sb.Append(input[i]);
130 i++;
131 label:
132 ;
133 }
134 else
135 {
136 sb.Append(input[i]);
137 i++;
138 }
139 }
140 return sb.ToString();
141 }
142 }
(4)例子
1 StringBatchFilter sk = new StringBatchFilter();
2
3 PairString[] p =
4 {
5 new PairString(Environment.NewLine,"<br>"),
6 new PairString(" "," "),
7 new PairString("'","''",true,false)
8 };
9 sk.Init();
10 sk.FilterSet = p;
11 sk.Filter();
2
3 PairString[] p =
4 {
5 new PairString(Environment.NewLine,"<br>"),
6 new PairString(" "," "),
7 new PairString("'","''",true,false)
8 };
9 sk.Init();
10 sk.FilterSet = p;
11 sk.Filter();
一般来说,如果待换字符串在10个以下,使用Replace性能较高。10个以上的,批量替换的优势就体现出来了。
版权所有,欢迎转载