我正在尝试制作一个程序来删除句子或短语中的所有元音。我没有语法错误,但是当我添加像'酷'这样的单词或者两个以上元音相邻的任何单词时,并不是所有这些都被删除了。为什么是这样? 这是我的代码:
procedure TForm1.btnProcessClick(Sender: TObject);
Var Sentence: string;
K : integer;
Begin
Sentence :=uppercase(edtSentence.text);
For k := 1 to length(sentence) do
If (sentence[k] in ['A', 'E', 'I', 'O', 'U']) then
begin
Delete(sentence,k,1);
Lbloutput.caption := sentence;
end;
答案 0 :(得分:3)
你在删除而不是倒计时时正在计算。
你的循环应该是: -
For K := Length(Sentence.Text) DownTo 1 Do
答案 1 :(得分:0)
您可以循环遍历所有字符并以这种方式删除它们,或者您可以使用StringReplace。唯一的缺点是你必须分别用它来代替每个元音。
procedure TForm1.btnProcessClick(Sender: TObject);
Var Sentence: string;
Begin
Sentence:=edtSentence.text; //No need to capitalize the string
Sentence:=StringReplace(Sentence, 'a', '', [rfReplaceAll, rfIgnoreCase]);
Sentence:=StringReplace(Sentence, 'e', '', [rfReplaceAll, rfIgnoreCase]);
Sentence:=StringReplace(Sentence, 'i', '', [rfReplaceAll, rfIgnoreCase]);
Sentence:=StringReplace(Sentence, 'o', '', [rfReplaceAll, rfIgnoreCase]);
Sentence:=StringReplace(Sentence, 'u', '', [rfReplaceAll, rfIgnoreCase]);
end;
答案 2 :(得分:0)
其他答案是正确的替代解决方案。但是,你的部分q是“为什么会这样?”
这基本上是因为“for K:= [...]”假定Sentence的长度在“for”循环的持续时间内是固定的,但是你在其中执行的操作,调用Delete()会改变句子的长度,所以这样做,你就是在自己的脚下拉地毯。
我更喜欢考虑这个编码问题的方式是与机场登记队列类比。
您计算队列中的人数(“...到长度(句子)”;请注意,对于“for ...”,这只发生一次,在循环开始之前)
您从正面开始按顺序扫描队列(“对于K:= 1 [...]”)
当你遇到可疑的人时,你将他们拉出队列(“删除([...]”)
拉人后面的每个人都向前移动一个地方(当你删除一个角色时,与句子相同)。
但是你(错误地)继续在队列中的下一个地方上继续扫描,这是一个超出该人退出的地方,而不是下一个人 b>在他/她之后。所以你想念排在队伍中的恐怖分子。
不仅如此,您还决定在开始扫描之前要扫描多少人(“[...]到长度(句子)”),但队列缩短了你的人数我们退出了,所以最终你会到达处理不再占用的地方的地步。如果您在观察窗口中观看Sentence [K],您会看到它在大于目前为止删除的字符数的位置处评估为#0。
因此,每当您的循环处理可能会改变您正在处理的事物的长度时,请在每次更改后重新检查长度,并检查您是否在正确的点恢复处理。这个,顺便说一下,是为了制作循环的东西之一。