我必须写一个程序来计算字符串中有多少个不同的字母。例如“abc”会给予3;“abcabc”也会给予3,因为只有3个不同的字母。
我需要使用pascal,但如果你能帮助在不同的语言代码,这将是非常好的了。
下面是我的代码不工作:
var s:string;
i,j,x,count:integer;
c:char;
begin
clrscr;
Readln(s);
c:=s[1];
x:=1;
Repeat
For i:=1 to (length(s)) do
begin
If (c=s[i]) then
begin
delete(s,i,1);
writeln(s);
end;
end;
c:=s[1];
x:=x+1;
Until length(s)=1;
Writeln(x);
x是不同字母计数器;也许我的算法很糟糕..有什么想法吗?谢谢。
9条答案
按热度按时间brjng4g31#
你已经知道怎么做了,这就是为什么你的方法不起作用。
首先,直觉告诉你一个好主意:从字符串中的第一个字符开始计数(你忘了包含计数代码),删除字符串中出现的所有相同字符,这个想法效率很低,但它是可行的,你在这段代码中遇到了麻烦:
问题是,Pascal在设置循环时会取
Length(s)
的值,但是你的代码通过移除字符来改变字符串的长度(使用delete(s,i,1)
)。你最终会看到坏内存。第二个问题是i
会前进,它是否匹配并移除字符并不重要。下面是坏内存的原因。我们将测试i= 1,2,3,4,5,寻找
a
,当i
为1时,我们将找到一个匹配项,去掉第一个字符,字符串将如下所示:现在我们使用i=2进行测试,结果不匹配,因为s[2] =b。我们刚刚跳过了一个
a
,而给定的a
将在数组中停留另一轮,导致算法计算它两次。“固定”算法如下所示:这是不同的:在给出的例子中,如果我在
1
处找到了匹配项,光标就不会前进,所以它看到的是第二个a
,而且因为我使用的是while
循环,而不是for
循环,所以我不会在for循环的可能实现细节上遇到麻烦。你的算法还有另一个问题,在删除了string中第一个字符的循环之后,你准备使用下面的代码进行下一个循环:
c:=s[1];
问题是,如果你给这个算法输入一个
aa
形式的字符串(长度=2,两个相同的字符),它将进入循环,删除或出现a
(那些将s变成空字符串的字符),然后试图读取空字符串的第一个字符。最后一句话:你的算法应该处理输入的空字符串,返回count=0。下面是固定的算法:
z4iuyo4d2#
我是一个 Delphi Maven,所以我不太清楚普通Pascal有多严格。不过,这是Delphi:
第一行可以写成
如果您无法使用Windows API(或 Delphi
FillChar
函数)。如果您希望支持Unicode(如在 Delphi 2009+中),您可以
shyt4zoc3#
这是我的版本。我并不是说如果你把这个交上来,你的作业会得高分。
n3h0vuf24#
使用 Delphi 构造(效率不高,但干净)
svdrlsy45#
不同的语言可以吗?
你好
nwo49xxi6#
一个 Delphi 版本。和@The Communist Duck Python版本的想法一样。
rta7y2nd7#
只是在抛出一个
set
-替代品...kxeu7u2r8#
在Python中,如果你想把它用于其他语言,可以附带解释:(因为您需要不同的语言)
ztyzrc3y9#