我需要删除以点结尾的字符串中的短字(短三个符号)。然后显示没有这些单词的字符串。
所以我们需要一个来自用户的字符串作为这样的输入:“这是一个人类型的简单字符串。”在该字符串中,程序应删除每个短于三个符号的单词。在我们的字符串中,这些是:“是,a,a”。所以输出应该是“这个简单的字符串人类型。”
这是我编程课程的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.
另一个小问题是:如何在成功运行后重新启动控制台应用程序?在这里,我使用标签和转到。也许还有另一种好方法可以再做一次吗?
答案 0 :(得分:2)
在这种情况下,请查找单词分隔符。在你的情况下,它是空间&#39;。此外,计算点之前的最后一个单词,因为它没有跟随&#39;空格&#39;。
编写主循环的一种方法是:
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;
答案 1 :(得分:1)
控制变量的Platform
循环开始值和结束值仅评估一次。您将结束值设置为字符串的长度。但是,在循环期间,您从字符串中删除部分,因此结束值超过字符串的结尾。尝试使用for
循环或while
循环。
错误的实际原因在
行repeat .. until
循环会持续多久?循环结束了什么?
您还需要重新考虑使用 while (UserString[i] <> ' ') do inc(n);
计算字符的方式。
答案 2 :(得分:1)
再次感谢大家指出正确的方向。我终于想出了我最初想要的解决方案,这样程序实际上删除了短(少于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.
欢迎任何建议!还有一个关于在控制台模式下重复程序的问题。标签是最好的方法吗(参见问题部分的第一个代码)?
答案 3 :(得分:1)
另一种方法:
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.