2011-03-06 62 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字符串!我很抱歉! –

相關問題