struct item { public string A; public string B; }string txtData="abcdefghigklmnopq"; item []items=...... foreach(item i in items){ txtData.Replace(i.A,i.B); }
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); }
struct item
{
public string A;
public string B;
}string txtData="abcdefghigklmnopq";
item []items=......
foreach(item i in items){
txtData.Replace(i.A,i.B);
}
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);
}
假设item[i].B的与item[j].A有交集的话,问题就复杂了
因为按不同顺序执行item[]替换结果可能不同的优化item[]的数据结构将替换条件以A为路径用树来存储例如,替换条件有abc、acd、ace
a-b-c
|
-c-d
|
-e外循环遍历字符串txtData,在这个树中进行查找应该比遍历item[]数组要高
a-b-c
|
-c-d
|
-e
关于item.B与item.A的交集问题我还真没想过,不过,在这个问题上,item.B和item.A不会有交集,也必须避免出现交集。
用树来存item[]然后遍历txtData,可以考虑一下。
这样吧。如果你的item数据结构可改么?
你的更新操作频繁么?两个问题。先了解后然后再给想法吧,否则没有解决的基点。
string str = "abc1312412abc3412413abc";
str = System.Text.RegularExpressions.Regex.Replace(str, item.A, item.B);
MessageBox.Show(str);正则表达式来处理大字符串的效率一般要高于string类的方法。
嗯,这就好办了。
首先吧……我记得string 类型的赋值是,如果你返回的是同一个字串的话,那么返回的将是同一个引用值,不会对字符串建立一个新的复本……那么,这样的话,替换的效率与字串的大小应该是没有什么关系的吧。你是真遇到效率的问题了,还是只是认为这会对效率产生影响呢?
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就见仁见智了。
对每个进行替换必须逐一遍历……保证每一步遍历的算法复杂度最优就好了。同源字串返回引用,复杂度为0(1),最快了。
item[]里面事先有没有txtData的文本?如果有,那么此问题不成立。如果没有,需要重新赋值的话呢……就是很慢……原本复制和建立过程就是线性的,没有更快的方法。
这个测试代码象是有点偏面了,对用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] : "";
}));
}
item[]里面事先有没有txtData的文本?如果有,那么此问题不成立。 这个是指什么情况呢,没看懂。是否是指item[].A事先有txtData的子符串呢?
不是子串,是完全的所需要的字串。
哪怕差一个字符,都会造成一个新的复本的创建。这就是string
深度复制过程至少是线性的……
老实说我越听越迷糊了,我是要把txtData中的item.a替换成item.b,怎么会把txtData复制到item[]呢?
其实我也很糊涂,你把item.a到item.b,与txtData有什么关系。
如是说,传引用。复杂度为0(1),对item[]进行线性遍历,就这样,没法再快了。
不是item.a到item.b,是把txtData中的item.a字符串替换成item.b,是txtData.replace(item.a,item.b)。就是这个意思...
明白了……
盖了那么多楼吧,其实……结果挺令人失望的……
深度复制,至少是线性……你这等于是文本替换是吧……没有更好的方法。其实你是知道该怎么办的,没法再快了。你要是嫌 string.Replace慢,就自己写一个Replace……不过效率上我想几乎不会有什么改观吧,不值当的。除非你更改你的文件组织形式,让文件可以合并相同的字串并保留引用,也就是说,建个字典,置索引……就好像MS的应用程序集那样的。不过你就不能以普通TXT类的文本文档来对待它了,而且只有你能处理这种文档。