现在流行写心得, 俺也来一篇。 如何高效地操作字符串。 给初学者一点帮助。 (鲜花和板砖都欢迎)(0分)

  • 主题发起人 主题发起人 Another_eYes
  • 开始时间 开始时间
很显然,长字符串的长度就在 -4 偏移处,取出它来用不了什么的开销。
// 没等我看到结果我先就死机了
那是你载入导致的吧,与查找无关。因为我试过:)
 
我也插一句: 处理字符串传递参数时传pchar类型和长度两个参数是个好方法。 不过这种方法虽然高效, 但有一定限制。 即一般你在过程中就不再进行边界检查了(相信传进来的是个正确的数值)。 如果还要进行边界检查, 那么第二个长度参数就没有意义了(除非你处理的不是字符串或者字符串中包含有#0字符)。 所以一般这种过程都定为全局过程的子过程使用, 简言之, 不对外开放。 这样安全和效率就都有保障了。
 
呵呵呵呵, Another_eYes ,您好啊。DFW 不给改名字啊,真有必要改一改了,
以后叫我小雨就行。呵呵。
 
那偶最小咯。:(
 
小雨哥 大叔(按照你的年龄分析,我该这样叫了[:)])
多点耐性,用 5M 的测吧:)
 
to 小雨哥: 说到测试, 相差在10ms左右的都不算差异的。 (操作系统本身的误差)。 不过字符串操作效率这种测试数据量一定要大, 100k是看不什么的。
再说生成个10M数据也不是什么很困难的时吧。请参看我心得的第二篇。里面测试数据的生成10M只用120-240ms(顺便自夸一句:10M字符串的替换用了不到1.5秒, 不过我记得我原来写过一个过程,操作15M数据只有不到700ms的,可我忘了到底怎么实现的。 现在怎么也达不到这个水平了。 真奇怪)。
能否到那里去讨论呀。 也给那里增加点人气。
 
beta 你 20 ,我知道。智者为大。我傻乎乎的,叫大了不好。
Another_eYes 的第二篇也没有在这里声明的,我就给个链接吧。
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1414550
 
beta:看来以后在这种共用函数中要写上自己的email了,否则,别人修改过都
不知道,哈哈。要是没有eyes的文章,我岂不是不知道FastReplace还有
这种Bug。孙老大也不做一个精华区,很多文章就这样被淹没了。再过几
个月,还能有多少人能有荣幸看到eyes的这几篇文章啊。
 
DreamTiger:
呵呵,精华区的事情,“民间”投票都搞了好几次了,可惜孙老师他老人家
常年不见人啊,soul 又特别忙,所以还是搁下了:(不过话又说回来,大家
都是用业余时间,这也没有办法。不可能像 CSDN 那样,人家有专人负责,
整天就搞这个,不用顾虑别的,毕竟人家可以靠这个吃饭啊,而我们不行:(
另:// 我岂不是不知道FastReplace还有这种Bug
呵呵,我也是用着用着,发现出现异常,才知道的:)随手改了一下而已。
早知道你在用,我就告诉你一声:)
 
好东东,收藏。
其实,看起来“基础”的东西,是需要底温的,所谓高手,我认为其中一点是“社会责任,就是
对下一代的教育”。这点,BETA 以及Another_eYes的做法,我觉得很是让人感动,值得至少我认为
是值得我学习。向两位致敬。
 
其实对基础了解得这么透彻的才是真正意义上的高手。以前有人问什么是 Delphi 的高级
技术,我当时回问了很多基础问题,始终我还是认为这些就是 Delphi 的高级技术。
另外 barton 的算法如果改成 Another_eYes 在第二篇描述的插入点替代法呢,不知道可
不可以。(使用一个二维动态数组记录二种点位置,二维数组也是可以被优化寻址的)
 
非常感谢Another_eYes大侠给大家做的精彩分析。
其实,Another_eYes所说的实质问题就是“循环的效率的问题”。
与此类似,上海贝尔公司的林锐博士在他的《高质量的C++编程指南》一书中也举了一个很
不错的例子:
for (row=0;
row<100;
row++)
{
for ( col=0;
col<5;
col++ )
{
sum = sum + a[row][col];
//低效率:长循环在最外层
}
}
for (col=0;
col<5;
col++ )
{
for (row=0;
row<100;
row++)
{
sum = sum + a[row][col];
//高效率:长循环在最内层
}
}
在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,
以减少CPU跨切循环层的次数
 
我一直在想,DFW2003年终盘点应该谁来写呢。
去年我一直在观望,直到年前的两天发现没有任何动静,我才只好滥竽充数
粗制滥造了一篇,实在很对不起观众啊。
今年就不要让我失望了把:-p
 
[:)]
很有价值,于微妙处见功夫!
佩服,学习!
希望能多见一些这样的贴子。[^]
 
请教一下,我这样写为什么得不到应得的结果?
如果str1不包含'f',就得不到正确结果,有时还报错,为什么?
procedure TForm1.Button2Click(Sender: TObject);
var
str1, str2: string;
begin
Str1 := 'sdgasdgsdgasdgas';
Str2 := string(@Str1[3]);
Label1.Caption := IntToStr(Pos('f', Str2));
end;
 
有金砖我一定扔。
 
看了Another_eYes的3,产生了一个疑惑,string(@Source)是否正确?
经过测试验证了我的猜测,绝对不可以这么用。
很简单的一个测试
var
s1,s2:string;
begin
s1:='111111111111111111111111221111111';
s2:=string(@s1[10]);
//请自己改变下标值,反复做测试。8会出致命错。
showmessage(IntToStr(Longint(s1))+' - '+IntToStr(Longint(s2)));
showmessage(IntToStr(pos('22',s2)));
showmessage(s1);
showmessage(s2);
end;
各位可以发觉pos的结果是大致正确的,但要命的是s2的显示根本不行,甚至会出错。甚至崩溃。
为何会这么样呢?
string(@s1[10])这句的意思是先取出 s1[10]指针,也就是实际存放s1[10]的内存地址,
然后把这个地址当作一个string类型转换之。问题就再这里。在delphi里string从s[1]开始
放置了字符串,而在s[1]之前还放了长度和引用计数,长度是在delphi在给字符串分配内存
的时候设置的,引用计数更是delphi管理内存的依据。这句话一写。也就是意味着把字符串
前几个字符当作长度和引用计数处理了,这样一来这句话导致了delphi的内存管理的混乱,
在引用这个字符串的时候更会出现致命错误。pos不知道为何还基本正确。各位可以查查。
例子中各位还可以发现,s1被改写了,那是因为引用计数加1的缘故。
好了,效率固然重要,但不恰当的语句造成严重的混乱,这就不好了。
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
900
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部