删除 Pascal 字符串中的短词
Delete short words in a Pascal string
我需要删除以点结尾的字符串中的短词(短于三个符号)。然后显示没有这些词的字符串。
所以我们需要一个来自用户的字符串作为输入,如下所示:"This is a simple string a man types." 在这个字符串中,程序应该删除每个短于三个符号的单词。在我们的字符串中,这些是:"is, a, a"。所以输出应该是 "This simple string man types."
这是我的编程课程的 Pascal/Delphi 任务。
几天来我一直在思考这个简单的问题,显然 运行 不知道如何解决它并寻求您的帮助。我为主要部分尝试了不同的循环,主要是在空格之间找到少于三个符号的序列。我尝试调试了一段时间,但没有结果。
我使用 Lazarus 1.6.2、FPC 3.0 和 Mac OS X v10.11 (El Capitan)。我的代码如下:
VAR
UserString: string;
i, n: byte; // Counters for the symbols in the string. 'i' counts every symbol.
again: boolean; // In case we need to repeat the program again
UserAnswerRepeat: char;
label repeat_again;
BEGIN
again:=false;
repeat_again: // Label to repeat the program
Writeln('Enter your string (ended by a dot):');
Readln(UserString);
// MAIN LOOP:
n:=1; // 'n' counts symbols in the words
for i:=1 to length(UserString) do
begin
while (UserString[i] <> ' ') do inc(n); // Here I have Range Check Error. Don't know how to get rid of it.
if (UserString[n] <> ' ') and (n<3) then
begin
delete(UserString, i-n, n);
n:=1
end;
end;
Writeln('The result is: ', UserString);
Writeln('Do you want to repeat the program? (Y/N)');
Readln(UserAnswerRepeat);
if (UserAnswerRepeat = 'Y') or (UserAnswerRepeat = 'y') then
again:=true;
if (again = true) then
goto repeat_again;
END.
另一个小问题是:如何让您的控制台应用程序在成功 运行 后重复?这里我使用了 labels 和 goto。也许还有另一种好方法可以重做?
A for
控制变量的循环开始和结束值仅计算一次。您将结束值设置为字符串的长度。但是,在循环期间,您从字符串中删除了部分,因此结束值超过了字符串的末尾。尝试使用 while
循环或 repeat .. until
循环。
错误的实际原因在行
while (UserString[i] <> ' ') do inc(n);
循环会持续多久?什么结束了循环?
您还需要重新考虑如何使用 n
.
计算字符
在这种情况下寻找单词分隔符。在你的例子中是 'space'。另外,计算点之前的最后一个单词,因为它后面没有 'space'.
编写主循环的一种方法是:
var
LastPos, I: Integer;
Tmp, UserString: String;
begin
LastPos := 1;
Tmp := '';
for I := 1 to Length(UserString) do
begin
if (UserString[I] = ' ') or (I = Length(UserString)) then
begin
if (I - LastPos >= 3) then Tmp := Tmp + Copy(UserString, LastPos, I - LastPos + 1);
LastPos := I + 1;
end;
end;
UserString: = Tmp;
end;
再次感谢大家指出了正确的方向。我终于想出了我最初想要的解决方案,这样程序实际上删除了短的(少于 3 个符号)单词。这是我得到的:
VAR
UserString: string; //должна быть строка на 40 символов и точку в конце
i, n: byte;
BEGIN
Writeln('Enter the string:');
Readln(UserString);
i:=0;
n:=1;
repeat //MAIN LOOP:
inc(i);
if (UserString[i] = ' ') or (UserString[i] = '.') then
begin
if (i-n<3)then
begin
delete(UserString, n, i-n+1);
i:=n-1;
end;
n:=i+1
end
until (UserString[i] = '.') or (i>length(UserString));
Writeln('Result String: ', UserString);
END.
欢迎提出任何建议!还有一个关于让程序在控制台模式下重复的悬而未决的问题。标签是最好的方法吗(请参阅问题部分的第一个代码)?
另一种方法:
uses classes;
var v : TStringlist;
i : integer;
begin
v :=TStringlist.create;
v.strictdelimiter:=true;
v.delimiter:=' ';
v.delimitedtext:='This is a simple string a man types';
for i:=v.count-1 downto 0 do
if length(v[i])<3 then
v.delete(i);
writeln(v.delimitedtext);
v.free;
end.
我需要删除以点结尾的字符串中的短词(短于三个符号)。然后显示没有这些词的字符串。
所以我们需要一个来自用户的字符串作为输入,如下所示:"This is a simple string a man types." 在这个字符串中,程序应该删除每个短于三个符号的单词。在我们的字符串中,这些是:"is, a, a"。所以输出应该是 "This simple string man types."
这是我的编程课程的 Pascal/Delphi 任务。
几天来我一直在思考这个简单的问题,显然 运行 不知道如何解决它并寻求您的帮助。我为主要部分尝试了不同的循环,主要是在空格之间找到少于三个符号的序列。我尝试调试了一段时间,但没有结果。
我使用 Lazarus 1.6.2、FPC 3.0 和 Mac OS X v10.11 (El Capitan)。我的代码如下:
VAR
UserString: string;
i, n: byte; // Counters for the symbols in the string. 'i' counts every symbol.
again: boolean; // In case we need to repeat the program again
UserAnswerRepeat: char;
label repeat_again;
BEGIN
again:=false;
repeat_again: // Label to repeat the program
Writeln('Enter your string (ended by a dot):');
Readln(UserString);
// MAIN LOOP:
n:=1; // 'n' counts symbols in the words
for i:=1 to length(UserString) do
begin
while (UserString[i] <> ' ') do inc(n); // Here I have Range Check Error. Don't know how to get rid of it.
if (UserString[n] <> ' ') and (n<3) then
begin
delete(UserString, i-n, n);
n:=1
end;
end;
Writeln('The result is: ', UserString);
Writeln('Do you want to repeat the program? (Y/N)');
Readln(UserAnswerRepeat);
if (UserAnswerRepeat = 'Y') or (UserAnswerRepeat = 'y') then
again:=true;
if (again = true) then
goto repeat_again;
END.
另一个小问题是:如何让您的控制台应用程序在成功 运行 后重复?这里我使用了 labels 和 goto。也许还有另一种好方法可以重做?
A for
控制变量的循环开始和结束值仅计算一次。您将结束值设置为字符串的长度。但是,在循环期间,您从字符串中删除了部分,因此结束值超过了字符串的末尾。尝试使用 while
循环或 repeat .. until
循环。
错误的实际原因在行
while (UserString[i] <> ' ') do inc(n);
循环会持续多久?什么结束了循环?
您还需要重新考虑如何使用 n
.
在这种情况下寻找单词分隔符。在你的例子中是 'space'。另外,计算点之前的最后一个单词,因为它后面没有 'space'.
编写主循环的一种方法是:
var
LastPos, I: Integer;
Tmp, UserString: String;
begin
LastPos := 1;
Tmp := '';
for I := 1 to Length(UserString) do
begin
if (UserString[I] = ' ') or (I = Length(UserString)) then
begin
if (I - LastPos >= 3) then Tmp := Tmp + Copy(UserString, LastPos, I - LastPos + 1);
LastPos := I + 1;
end;
end;
UserString: = Tmp;
end;
再次感谢大家指出了正确的方向。我终于想出了我最初想要的解决方案,这样程序实际上删除了短的(少于 3 个符号)单词。这是我得到的:
VAR
UserString: string; //должна быть строка на 40 символов и точку в конце
i, n: byte;
BEGIN
Writeln('Enter the string:');
Readln(UserString);
i:=0;
n:=1;
repeat //MAIN LOOP:
inc(i);
if (UserString[i] = ' ') or (UserString[i] = '.') then
begin
if (i-n<3)then
begin
delete(UserString, n, i-n+1);
i:=n-1;
end;
n:=i+1
end
until (UserString[i] = '.') or (i>length(UserString));
Writeln('Result String: ', UserString);
END.
欢迎提出任何建议!还有一个关于让程序在控制台模式下重复的悬而未决的问题。标签是最好的方法吗(请参阅问题部分的第一个代码)?
另一种方法:
uses classes;
var v : TStringlist;
i : integer;
begin
v :=TStringlist.create;
v.strictdelimiter:=true;
v.delimiter:=' ';
v.delimitedtext:='This is a simple string a man types';
for i:=v.count-1 downto 0 do
if length(v[i])<3 then
v.delete(i);
writeln(v.delimitedtext);
v.free;
end.