How many different letters per line

I need to write a program that counts the number of different letters in a string. For example, "abc" will give 3; and "abcabc" will also give 3 because there are only 3 different letters.

I need to use pascal, but if you can help with code in different languages, this will be very good too.

Here is my code that does not work:

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 is another letter counter; Maybe my algorithm is very bad ... any ideas? Thanks.

+8
string delphi pascal
source share
9 answers

You have answers to the question of how to do this, which is why your path does not work.

First of all, you had a good idea: start with the first char in the line, count it (you forgot to include the counting code), delete all occurrences of the same char in the line. The idea is ineffective, but it will work. You are having trouble with this piece of code:

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

The problem is that Pascal will take the value of Length(s) when it sets the loop, but your code changes the length of the string by deleting characters (using delete(s,i,1) ). You end up looking at bad memory. The second problem is that i will move forward, it doesn't matter if it matches and removes char or not. That is why it is bad.

 Index: 12345 String: aabbb 

You are going to check i = 1,2,3,4,5 by looking for a . When i is 1, you will find a match, remove the first char, and your line will look like this:

 Index: 1234 String: abbb 

Now you are testing i = 2, and this does not match, because s [2] = b. You just missed one a , and that the given a will contain another round in the array and force your algorithm to read it twice. The “fixed” algorithm will look like this:

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

This is different: in this example, if I find a match at 1 , the cursor does not move, so it sees the second a . Also, because I'm using a while , not a for loop, I can't run into the possible details of implementing a for loop.

Your algorithm has another problem. After a loop that deletes all occurrences of the first char string in the string, you prepare the next loop using this code:

C: = s [1];

The problem is that if you feed this algorithm into a line of the form aa (length = 2, two identical characters), it will enter a loop, delete or occurrences of a (which turn s into EMPTY), and then try to read the first char of the EMPTY line .

Last word: your algorithm should process an empty input line, returning count = 0. Here's a fixed algorithm:

 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. 
+11
source share

I am a Delphi expert, so I don’t quite understand how restrictive simple Pascal is. However, this is 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; 

The first line can be written

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

if you cannot use the Windows API (or the Delphi FillChar function).

If you want to have Unicode support (as in Delphi 2009+), you can do

 // 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; 
+4
source share

Here is my version. I am not saying that you will get an excellent mark in your assignment if you pass it on.

 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; 
+4
source share

Are different languages ​​alright?

RUBY:

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

Delphi version. Same idea as @The Commun 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; 
+2
source share

Just tossing an alternative ...

 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. 
+2
source share

And using the Delphi construct (not efficient, but clean)

 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; 
+2
source share

In Python with an explanation if you want it for any other language: (since you wanted different languages)

 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 
+1
source share
 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; 
0
source share

All Articles