delphi 字符串中有多少个不同的字母

6yoyoihd  于 2023-02-08  发布在  其他
关注(0)|答案(9)|浏览(109)

我必须写一个程序来计算字符串中有多少个不同的字母。例如“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是不同字母计数器;也许我的算法很糟糕..有什么想法吗?谢谢。

brjng4g3

brjng4g31#

你已经知道怎么做了,这就是为什么你的方法不起作用。
首先,直觉告诉你一个好主意:从字符串中的第一个字符开始计数(你忘了包含计数代码),删除字符串中出现的所有相同字符,这个想法效率很低,但它是可行的,你在这段代码中遇到了麻烦:

For i:=1 to (length(s)) do
begin
  If (c=s[i]) then
  begin
    delete(s,i,1);
  end;
end;

问题是,Pascal在设置循环时会取Length(s)的值,但是你的代码通过移除字符来改变字符串的长度(使用delete(s,i,1))。你最终会看到坏内存。第二个问题是i会前进,它是否匹配并移除字符并不重要。下面是坏内存的原因。

Index:  12345
String: aabbb

我们将测试i= 1,2,3,4,5,寻找a,当i为1时,我们将找到一个匹配项,去掉第一个字符,字符串将如下所示:

Index:  1234
String: abbb

现在我们使用i=2进行测试,结果不匹配,因为s[2] =b。我们刚刚跳过了一个a,而给定的a将在数组中停留另一轮,导致算法计算它两次。“固定”算法如下所示:

i := 1;
while i <= Length(s) do
  if (c=s[i]) then
    Delete(s,i,1)
  else
    Inc(i);

这是不同的:在给出的例子中,如果我在1处找到了匹配项,光标就不会前进,所以它看到的是第二个a,而且因为我使用的是while循环,而不是for循环,所以我不会在for循环的可能实现细节上遇到麻烦。
你的算法还有另一个问题,在删除了string中第一个字符的循环之后,你准备使用下面的代码进行下一个循环:
c:=s[1];
问题是,如果你给这个算法输入一个aa形式的字符串(长度=2,两个相同的字符),它将进入循环,删除或出现a(那些将s变成空字符串的字符),然后试图读取空字符串的第一个字符。
最后一句话:你的算法应该处理输入的空字符串,返回count=0。下面是固定的算法:

var s:string;
    i,count:integer;
    c:char;
begin
  Readln(s);
  count:=0;

  while Length(s) > 0 do
  begin
    Inc(Count);
    c := s[1];
    i := 1;
    while i <= Length(s) do
    begin
      If (c=s[i]) then
        delete(s,i,1)
      else
        Inc(i);
    end;
  end;

  Writeln(Count);

  Readln;
end.
z4iuyo4d

z4iuyo4d2#

我是一个 Delphi Maven,所以我不太清楚普通Pascal有多严格。不过,这是Delphi:

// Returns the number of *distinct* "ANSI" characters in Str
function NumChrs(const Str: AnsiString): integer;
var
  counts: array[0..255] of boolean;
  i: Integer;
begin
  ZeroMemory(@counts[0], sizeof(boolean) * length(counts));
  for i := 1 to length(Str) do
    counts[ord(Str[i])] := true;
  result := 0;
  for i := 0 to high(counts) do
    if counts[i] then
      inc(result);
end;

第一行可以写成

for i := 0 to high(counts) do
    counts[i] := false;

如果您无法使用Windows API(或 Delphi FillChar函数)。
如果您希望支持Unicode(如在 Delphi 2009+中),您可以

// Returns the number of *distinct* Unicode characters in Str
function NumChrs(const Str: string): integer;
const
  AllocBy = 1024;
var
  FoundCodepoints: array of integer;
  i: Integer;

  procedure Push(Codepoint: integer);
  var
    i: Integer;
  begin
    for i := 0 to result - 1 do
      if FoundCodepoints[i] = Codepoint then
        Exit;
    if length(FoundCodepoints) = result then
      SetLength(FoundCodepoints, length(FoundCodepoints) + AllocBy);
    FoundCodepoints[result] := Codepoint;
    inc(result);
  end;  

begin

  result := 0;
  for i := 1 to length(Str) do
    Push(ord(Str[i]));

end;
shyt4zoc

shyt4zoc3#

这是我的版本。我并不是说如果你把这个交上来,你的作业会得高分。

function NumberOfUniqueChars(s: string): Integer;
var
  i, j: Integer;
  c: char;
begin
  for i := 1 to Length(s) do
    for j := i+1 to Length(s) do
      if s[i]<s[j] then
      begin
        c := s[i];
        s[i] := s[j];
        s[j] := c;
      end;
  Result := 0;
  for i := 1 to Length(s) do begin
    if (i=1) or (s[i]<>c) then
      inc(Result);
    c := s[i];
  end;
end;
n3h0vuf2

n3h0vuf24#

使用 Delphi 构造(效率不高,但干净)

function returncount(basestring: String): Integer;
var charstrings: TStringList;
    I:Integer;
begin
Result := 0;
charstrings := TStringlist.create;
try    
  charstrings.CaseSensitive := False;
  charstrings.Duplicates := DupIgnore;
  for I := 1 to length(basestring) do 
    charstrings.Add(basestring[i]);
  Result := charstrings.Count;
finally
  charstrings.free;
end;
end;
svdrlsy4

svdrlsy45#

不同的语言可以吗?
你好

s = "abcabc"
 => "abcabc"
m = s.split(//)
 => ["a", "b", "c", "a", "b", "c"]
p = m & m
 => ["a", "b", "c"]
p.count
 => 3
nwo49xxi

nwo49xxi6#

一个 Delphi 版本。和@The Communist Duck Python版本的想法一样。

function GetNumChars(Str: string): Integer;
var
    s: string;
    c: Char;
begin
    s := '';
    for c in Str do
    begin
        if Pos(c, s) = 0 then
        begin
            s := s + c;
        end;
    end;
    Result := Length(s);
end;
rta7y2nd

rta7y2nd7#

只是在抛出一个set-替代品...

program CountUniqueChars;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  InputStr: String;
  CountedChr: Set of Char;
  TotalCount: Integer;
  I: Integer;
begin
  Write('Text: ');
  ReadLn(InputStr);

  CountedChr := [];
  TotalCount := 0;

  for I := 1 to Length(InputStr) do
  begin
    Write('Checking: ' + InputStr[i]);
    if (InputStr[i] in CountedChr)
    then WriteLn('  --')
    else begin
      Include(CountedChr, InputStr[i]);
      Inc(TotalCount);
      WriteLn('  +1')
    end;
  end;

  WriteLn('Unique chars: ' + IntToStr(TotalCount));
  ReadLn;
end.
kxeu7u2r

kxeu7u2r8#

在Python中,如果你想把它用于其他语言,可以附带解释:(因为您需要不同的语言)

s = 'aahdhdfrhr' #s is the string
l = [] #l is an empty list of some kind.
for i in s: #Iterate through the string
    if i not in l: #If the list does not contain the character
        l.append(i) #Add the character to the list
print len(l) #Print the number of characters in the list
ztyzrc3y

ztyzrc3y9#

function CountChars(const S:AnsiString):Integer;
var C:AnsiChar; CS:Set of AnsiChar;
begin
  Result := 0;
  CS := [];
  for C in S do
    if not (C in CS) then
    begin
      CS :=  CS + [C];
      Inc(Result);
    end;
end;

相关问题