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

时间:2011-03-05 20:04:04

标签: string delphi pascal

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

9 个答案:

答案 0 :(得分:11)

你已经得到了如何做到的答案,这就是你的方式不起作用的原因。

首先,你有一个好主意:从字符串中的第一个字符开始,计算它(你忘了包含计数代码),删除字符串中所有出现的相同字符。这个想法是低效的,但它会起作用。你遇到了这段代码的麻烦:

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循环的可能实现细节遇到麻烦。

您的算法还有其他问题。在删除字符串中所有第一个字符串的循环之后,您将使用以下代码准备下一个循环:

C:= S [1];

问题是,如果你为这个算法提供一个aa形式的字符串(长度= 2,两个相同的字符),它将进入a的循环,删除或出现(那些将s转换为EMPTY字符串)然后尝试读取EMPTY字符串的第一个字符。

最后一句话:您的算法应该在输入时处理空字符串,返回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.

答案 1 :(得分:4)

我是Delphi的专家,所以我不太清楚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;

答案 2 :(得分:4)

这是我的版本。如果你把它交给我,我并不是说你的作业会得到很好的印记。

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;

答案 3 :(得分:3)

使用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;

答案 4 :(得分:2)

不同的语言可以吗?

RUBY:

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

答案 5 :(得分:2)

Delphi版本。与@The 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;

答案 6 :(得分:2)

只是扔进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.

答案 7 :(得分:1)

在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

答案 8 :(得分:0)

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;