zoukankan      html  css  js  c++  java
  • 批量字符串替换程序

            很多时候我们需要用到字符串替换程序,比如插入数据库时需要将'替换成''。当只有少数待换字符串时用String.Replace性能很高,但因为其复杂度是O(n),当待换字符串很多的时候,String.Replace的性能就降下来了。前些天写了几个程序,用于批量替换字符串。

    问题:批量替换字符串。定义字符串对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)采用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    }

    (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    }

    (4)例子

     1    StringBatchFilter sk = new StringBatchFilter();
     2
     3    PairString[] p =
     4     {
     5         new PairString(Environment.NewLine,"<br>"),
     6         new PairString("    ","&nbsp;&nbsp;&nbsp;&nbsp;"),
     7         new PairString("'","''",true,false)
     8     }
    ;
     9    sk.Init();
    10    sk.FilterSet = p;
    11    sk.Filter();

    一般来说,如果待换字符串在10个以下,使用Replace性能较高。10个以上的,批量替换的优势就体现出来了。
    版权所有,欢迎转载
  • 相关阅读:
    Linux常用命令--清屏
    [LeetCode]Remove Duplicates from Sorted Array
    [LeetCode]Combinations
    [LeetCode]Search in Rotated Sorted Array II
    [LeetCode]Binary Tree Level Order Traversal II
    [LeetCode]Binary Tree Level Order Traversal
    [LeetCode]H-Index II
    [LeetCode]H-Index
    [LeetCode]Symmetric Tree
    [LeetCode]Remove Element
  • 原文地址:https://www.cnblogs.com/xiaotie/p/215160.html
Copyright © 2011-2022 走看看