struct item
{
   public string A;
   public string B;
}
现有一组item[]和一字符串txtData,需要将 txtData 中的 item.A 替换成 item.B值。由于item[]长度可能比较长及txtData字符串也会比较大。所以想寻求一种比较有效率的替换方式。

解决方案 »

  1.   


    struct item
    {
       public string A;
       public string B;
    }string txtData="abcdefghigklmnopq";
    item []items=......
    foreach(item i in items){
     txtData.Replace(i.A,i.B);
    }
      

  2.   


    struct item
    {
       public string A;
       public string B;
    }string txtData="abcdefghigklmnopq";
    item []items=......
    foreach(item i in items){
     txtData=txtData.Replace(i.A,i.B);
    }
      

  3.   

    谢谢1,2楼。但是,如果要那样作的话,我就不用来csdn来问了。谢谢。
      

  4.   

    先提醒楼主确定需求中替换条件item[]中的优先问题
    假设item[i].B的与item[j].A有交集的话,问题就复杂了
    因为按不同顺序执行item[]替换结果可能不同的优化item[]的数据结构将替换条件以A为路径用树来存储例如,替换条件有abc、acd、ace
    a-b-c
     |
     -c-d
       |
       -e外循环遍历字符串txtData,在这个树中进行查找应该比遍历item[]数组要高
      

  5.   


    a-b-c 
     | 
     -c-d 
       | 
       -e
      

  6.   


    关于item.B与item.A的交集问题我还真没想过,不过,在这个问题上,item.B和item.A不会有交集,也必须避免出现交集。
    用树来存item[]然后遍历txtData,可以考虑一下。
      

  7.   


    这样吧。如果你的item数据结构可改么?
    你的更新操作频繁么?两个问题。先了解后然后再给想法吧,否则没有解决的基点。
      

  8.   

    可以用正则表达式
                    string str = "abc1312412abc3412413abc";
                    str = System.Text.RegularExpressions.Regex.Replace(str, item.A, item.B);
                    MessageBox.Show(str);正则表达式来处理大字符串的效率一般要高于string类的方法。
      

  9.   


    嗯,这就好办了。
    首先吧……我记得string 类型的赋值是,如果你返回的是同一个字串的话,那么返回的将是同一个引用值,不会对字符串建立一个新的复本……那么,这样的话,替换的效率与字串的大小应该是没有什么关系的吧。你是真遇到效率的问题了,还是只是认为这会对效率产生影响呢?
      

  10.   

    以下是测试代码:
            static void Main(string[] args)
            {
                string segment = "中华aBc共和国";
                string source;
                string pattern = "abc";
                string destination = "人民";
                string result = "";
                const long count = 1000;
                StringBuilder pressure = new StringBuilder();
                HiPerfTimer time;            for (int i = 0; i < count; i++)
                {
                    pressure.Append(segment);
                }
                source = pressure.ToString();
        
                //regexp
                time = new HiPerfTimer();
                time.Start();
                for (int i = 0; i < count; i++)
                {
                    result = Regex.Replace(source, pattern, destination, RegexOptions.IgnoreCase);
                }
                time.Stop();            Console.WriteLine("regexp    =" + time.Duration + ":");
                //vb
                time = new HiPerfTimer();
                time.Start();
                for (int i = 0; i < count; i++)
                {
                    result = Strings.Replace(source, pattern, destination, 1, -1, CompareMethod.Text);
                }
                time.Stop();            Console.WriteLine("vb        =" + time.Duration + ":");
                //vbReplace
                time = new HiPerfTimer();
                time.Start();
                for (int i = 0; i < count; i++)
                {
                    result = VBString.Replace(source, pattern, destination, 1, -1, StringCompareMethod.Text);
                }
                time.Stop();            Console.WriteLine("vbReplace =" + time.Duration + ":" + result);
                //substring
                time = new HiPerfTimer();
                time.Start();
                for (int i = 0; i < count; i++)
                {
                    result = StringHelper.ReplaceText(source, pattern, destination, StringHelper.CompareMethods.Text);
                }
                time.Stop();            Console.WriteLine("substring =" + time.Duration + ":");
                //substring with stringbuilder
                time = new HiPerfTimer();
                time.Start();
                for (int i = 0; i < count; i++)
                {
                    result = StringHelper.ReplaceTextB(source, pattern, destination, StringHelper.CompareMethods.Text);
                }
                time.Stop();            Console.WriteLine("substringB=" + time.Duration + ":");
                Console.ReadLine();
            }
    说明这个代码演示了上述几种方法:要把字符串"中华aBc共和国"中的"abc"替换为"人民",注意:源子字符串是"aBc",要替换的是"abc",这里目的是要测试不区分大小写。为了测试效率,我特意先把测试字符串累加1000次,然后循环测试1000次。
    结果以下是测试结果:
    regexp      =1.38308285017339 //这是正则表达式,第3快;
    vb            =0.525978828344589 //这是引用Microsoft VisualBasic RunTime的,次快;
    vbReplace=0.522997341400086 //这就是用reflector改为C#的,最快;
    substring  =21.8573638474698 //这是string.substring +,最慢
    substringB=14.6346693500287 //这是string.substring StringBuilder,次慢,这里凸现了StringBuilder的速度;这里仅仅是多次测试中的一次,我没有弄平均,大概数字吧,到底是vb快还是reflector的c#快,差不多...是否应该使用Microsoft VisualBasic RunTime就见仁见智了。
      

  11.   


    对每个进行替换必须逐一遍历……保证每一步遍历的算法复杂度最优就好了。同源字串返回引用,复杂度为0(1),最快了。
    item[]里面事先有没有txtData的文本?如果有,那么此问题不成立。如果没有,需要重新赋值的话呢……就是很慢……原本复制和建立过程就是线性的,没有更快的方法。
      

  12.   


    这个测试代码象是有点偏面了,对用Regex,多次替换不见得每次都要Regex.Replace
    对于一次大文本替换象以下代码,一次replace就可以结束替换了,而其它方式是不是要多次替换呢?    public string regexReplace(string input)
        {
            Dictionary<string, string> values = new Dictionary<string, string>();
            values["A"] = "[替换结果]";
            values["B"] = "[替换结果]";
            values["C"] = "[替换结果]";
            values["D"] = "[替换结果]";
            values["E"] = "[替换结果]";
            values["F"] = "[替换结果]";
            values["G"] = "[替换结果]";
            string[] patterns = new string[values.Count];
            int x = 0;
            foreach (KeyValuePair<string, string> item in values)
            {
                patterns[x++] = item.Key;
            }        return Regex.Replace(input, string.Join("|", patterns),
                new MatchEvaluator(delegate(Match m)
                {
                    string key = m.ToString();
                    return values.ContainsKey(key) ? values[key] : "";
                }));
        }
      

  13.   


    item[]里面事先有没有txtData的文本?如果有,那么此问题不成立。 这个是指什么情况呢,没看懂。是否是指item[].A事先有txtData的子符串呢?
      

  14.   


    不是子串,是完全的所需要的字串。
    哪怕差一个字符,都会造成一个新的复本的创建。这就是string
      

  15.   

    如果你仅仅是将item.a 的内容给 ITEM.B 的话是传引用。如果你将txtData的内容复制到item[]中的话,那么……
    深度复制过程至少是线性的……
      

  16.   


    老实说我越听越迷糊了,我是要把txtData中的item.a替换成item.b,怎么会把txtData复制到item[]呢?
      

  17.   


    其实我也很糊涂,你把item.a到item.b,与txtData有什么关系。
    如是说,传引用。复杂度为0(1),对item[]进行线性遍历,就这样,没法再快了。
      

  18.   


    不是item.a到item.b,是把txtData中的item.a字符串替换成item.b,是txtData.replace(item.a,item.b)。就是这个意思...
      

  19.   


    明白了……
    盖了那么多楼吧,其实……结果挺令人失望的……
    深度复制,至少是线性……你这等于是文本替换是吧……没有更好的方法。其实你是知道该怎么办的,没法再快了。你要是嫌 string.Replace慢,就自己写一个Replace……不过效率上我想几乎不会有什么改观吧,不值当的。除非你更改你的文件组织形式,让文件可以合并相同的字串并保留引用,也就是说,建个字典,置索引……就好像MS的应用程序集那样的。不过你就不能以普通TXT类的文本文档来对待它了,而且只有你能处理这种文档。