2011-03-06 67 views
4

我有一个计划,用绳子(帕斯卡)的作品。如果第一个字符不是一个字母,那么在读取字符串之后,我需要删除所有的第一个字符,直到第一个字符为止。我试图写几次,但总是删除所有字符串或没有。如何从字符串中删除字符,直到第一个字符是一个字母?

如果程序上写着“123%^ & ABC”,那么结果应该是“ABC” 在ASCII表信件是从65..90和97..122

这是我有多远:

variables a: set of 65..90; 
      b: set of 97..122; 
------------------- 
    bool:=false; 
    While (bool=false) do 
    begin 
    Writeln(s[1]); 
    If (Ord(s[1]) in a) or (Ord(s[1]) in b) then 
    begin 
    bool:=true; 
    end else 
    delete(s,1,1); 
    end; 

我不明白为什么它不工作? 你可以帮我做这个小程序吗?谢谢。

+0

这是一段时间,因为我没有做一些帕斯卡,但你的程序似乎对我来说很好,你可以粘贴给定字符串的输出吗?或者最终的错误 – krtek

+1

而且,我一如既往地添加delphi标签,以便您的问题得到真正的关注! –

+0

我在该程序中看不到任何错误。我不喜欢它的风格,但我没有理由认为它不应该按照预期工作。 – CodesInChaos

回答

13

你可以做

function RemoveNonAlphaASCIIFromStart(const Str: AnsiString): AnsiString; 
const 
    ALPHA = ['A'..'Z', 'a'..'z']; 
var 
    i: Integer; 
    firstIndex: integer; 
begin 
    result := ''; 
    firstIndex := 0; 
    for i := 1 to length(Str) do 
    if Str[i] in ALPHA then 
    begin 
     firstIndex := i; 
     break; 
    end; 
    if firstIndex > 0 then 
    result := Copy(Str, firstIndex, length(Str)); 
end; 

,或者作为一个过程

procedure RemoveNonAlphaASCIIFromStart(var Str: AnsiString); 
const 
    ALPHA = ['A'..'Z', 'a'..'z']; 
var 
    i: Integer; 
    firstIndex: integer; 
begin 
    firstIndex := 0; 
    for i := 1 to length(Str) do 
    if Str[i] in ALPHA then 
    begin 
     firstIndex := i; 
     break; 
    end; 
    if firstIndex > 0 then 
    Delete(Str, 1, firstIndex - 1) 
    else 
    Str := ''; 
end; 

对于更复杂的方法,这也与Unicode的德尔福工作,看到my answer to a similar question。 [这消除了从字符串中的所有非字母字符。]

那么,为什么没有你的算法的工作?那么,它应该可以工作,并且对我有用。但是请注意,但是,可以写在稍微更优雅的形式

const 
    ALPHA = ['A'..'Z', 'a'..'z']; 

while true do 
    if (length(s) = 0) or (s[1] in ALPHA) then 
    break 
    else 
    delete(s, 1, 1); 

的一个问题,与OP的原代码是,如果s为空字符串,它会失败。的确,那么s[1]不存在。它不会工作,要么如果s完全由非字母字符(例如'!"#¤%)。

+0

工程很棒。谢谢。 –

+0

比OP更好的风格,但就像你我看到在原代码中没有错误。 – CodesInChaos

+1

请注意,我在最后一段代码中的'if'语句中依赖布尔短路评估(BSCE)。我不确定朴素的帕斯卡是否聘用了BSCE。 –

2

Allthough以前的解决方案做的工作,他们是高度ineffitient。由于2个原因: 1.在一个集合中搜索很耗时 2.每次从字符串中删除一个字符更加麻烦,因为字符串(对象)必须在内部删除字符并调整它的数组等。 。

理想情况下,你投你的字符串转换成PChar类型和工作与,同时检查字符范围“手动”。我们将让搜索运行直到找到第一个字母,然后我们调用DeleteString方法。这是我的方法演示:

procedure Frapp; 
var 
    TheString: string; 
    pcStr: PChar; 
    StrLen, I: Integer; 
begin 
    TheString := '123%^&abc'; 
    StrLen := Length(TheString); 
    pcStr := PChar(TheString); 

    for I := 0 to StrLen - 1 do 
    begin 
    if ((pcStr^ >= #65) and (pcStr <= #90)) or ((pcStr >= #97) and (pcStr <= #122)) then 
    begin 
     Delete(TheString, 1, I); 
     Break; 
    end; 
    Inc(pcStr); 
    end; 
end; 
+1

请注意,我的两种算法都没有遭受重复的“Delete”调用(这确实效率很低)。无论如何,你上面的代码不起作用... –

+0

我的歉意。你不会经常调用Delete。但为什么你说我的代码不起作用? – fmotis

+0

我试过了。它产生'^&abc',而不是预期的'abc'。更新:但我很急(然后赶上公车)!事实上,它不适用于* Delphi 2009 *和更高版本(它们是* Unicode *)!但它*可以使用纯ANSI字符串!我很抱歉! –

相关问题