批量字符串替换程序
很多时候我们需要用到字符串替换程序,比如插入数据库时需要将'替换成''。当只有少数待换字符串时用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

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

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

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

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

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

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

4

5

6

7

8

9

10

11



一般来说,如果待换字符串在10个以下,使用Replace性能较高。10个以上的,批量替换的优势就体现出来了。
版权所有,欢迎转载