1

Before someone asks, no, this is not homework (I can understand someone assuming it since it's a rather silly question), I'm just preparing myself for pascal since I will see it in a soon course and I'm putting myself some little chalenges and see what I can do about them, but I am most absolutely puzzled about this one.

Let's say I have a string of many numbers, let's say 2437341323 , and I would like to count those 3's.

For example, the number 3 appears 4 times in that string of numbers, so I'd like an output that is 4, so I can say "The number 3 shows up 4 times in this string".

How can I do this?

Excuse my bad english and thanks for your time reading this post, and if possible, answering it.

NineBerry
  • 26,306
  • 3
  • 62
  • 93
Markski
  • 21
  • 3

3 Answers3

3

In Pascal, you can treat a string like a 1-based array of characters, so you can simply iterate through the string, counting the characters you want to count:

function CountChar(const Ch: Char; const Str: string): Integer;
var
  i: Integer;
begin
  Result := 0;
  for i := 1 to Length(Str) do
    if Str[i] = Ch then
      Inc(Result);
end;

Sample use:

NumThrees = CountChar('3', '2437341323');

For older versions of Pascal that don't provide an automatic Result variable, declare Result as a variable local to the procedure and simply return it:

function CountChar(const Ch: Char; const Str: string): Integer;
var
  i, Result: Integer;
begin
  Result := 0;
  for i := 1 to Length(Str) do
    if Str[i] = Ch then
      Inc(Result);
  CountChar := Result;
end;
Ken White
  • 123,280
  • 14
  • 225
  • 444
0

Walk the string as an array from 1..length(mystring) then check each character as mstring[element]='3' Using the following procedure you can check for matches of more than just one characters so (this is for 2 byte strings - untested in older versions). Important info : when referencing strings as an array - remember that strings begin from element [1] rather than [0] as in most of the rest of pascal's default structures & classes.

For x:=1 to length(mystring) do
begin
     if IsSubStringAtPos(mystring,x,'333',True) then inc(MatchCount);
end;
Function IsSubstringAt(source:String;atPos:integer;Mask:String;CaseSensitive:boolean):Boolean;overload;
var
    SourceP,MaskP:PChar;
    sourceL,maskl:integer;
    i:integer;
begin
   result:=false;
   if source='' then exit;
   if mask='' then exit;
   if atpos<1 then exit;

   SourceL:=Length(Source);
   MaskL:=Length(mask);
   if atpos>SourceL-maskL+1 then exit;

   SourceP:=@Source[atpos];
   MaskP:=@Mask[1] ;

   result:=true; //now we can only fail and set false;
   for i:=1 to maskL do
   begin
        case CaseSensitive of
        True : Begin
                    if sourcep^<>maskp^ then
                    begin
                        result:=false;
                        break;
                    end;
                    inc(sourcep);
                    inc(maskp);
               end;
        False:Begin
                   if AnsiUpperCase(SourceP^)<>ansiuppercase(Maskp^) then
                   begin
                        result:=false;
                        break;
                   end;
                   inc(sourceP);
                   inc(maskP);
              end;
        end;//of case
   end;
-1

Traverse the string, being it that string is an array of char, and use an if statement to check for the appropriate character. In my example the character we are looking for is provided when the function is called.

function checkforchar(s:string;c:char):integer;
var
  i:integer;
begin
  checkforchar:=0;
  for i:=1 to length(s) do
    if s[i]=c then inc(checkforchar);
end;

When loops aren't provided with begin and end statements, considering if and case statements as well, they only run the next line of code. Keep in mind here that the stuff between a begin and an end; inclusive, a block of code, is picked up entirely by the loop or statement as if one line which is why this works.

--EDIT--

Here is a usage example.

fourspresent:=checkforchar(stringexample,'4');

If you would like to look for an entire string in the other string you can do as follows.

function checkforstring(s,s2:string):integer; {where s must be bigger than s2}
var
  i,e:integer;
  patched_s:string;
begin
  checkforstring:=0;
  for i:=1 to length(s)-length(s2)+1 do
  begin
    patched_s:='';

    for e:=i to i+length(s2)-1 do
      patched_s:=patched_s+s[e];

    if patched_s=s2 then inc(checkforstring);
  end;
end;
Dominic
  • 38
  • 6
  • This is exactly the code I've already posted in my answer (the second code block), with different variable and function name. What does it add that my answer didn't already provide? – Ken White May 26 '16 at 20:08
  • it provides the use of one less variable. – Dominic May 26 '16 at 20:21
  • I did not copy anybody's answer if that is what you are getting at. – Dominic May 26 '16 at 20:21
  • It also provided the asker of the question with a little insight on begin and end mechanics. – Dominic May 26 '16 at 20:22
  • I didn't say you copied anything. I simply asked what additional information you provided that wasn't already in an existing answer, to which your response is *None, but I added noise*. I don't see anywhere in the question that the poster asked for a lesson on *begin..end*, but if one is wanted I've already written one in [Proper structure for begin..end and ;](http://stackoverflow.com/a/28221465/62576). – Ken White May 26 '16 at 20:29
  • No, he did not ask for it, but everyone likes extra information. I don't know why you have to be so offensive, jeez. – Dominic May 26 '16 at 20:38
  • You've now posted two separate answers to this question, both of which simply repeat the code I've posted more than a month ago. While we appreciate people wanting to share knowledge, it doesn't accomplish anything to simply post the same answers as existing ones a month or more later, and certainly posting it twice isn't acceptable. Adding clutter to the site doesn't help anyone. – Ken White May 26 '16 at 20:43
  • you did not provide a way to check for string in another string Mr.White. – Dominic May 26 '16 at 20:45
  • So how exactly can you call that redundant. If anything you could have told me to put it all into one answer, but instead you tell me I have repeated myself when I clearly haven't. – Dominic May 26 '16 at 20:47
  • You're right, I didn't, because **that's not what the question asked**. I also didn't explain how to use multiple threads, access a database, call Windows API functions, or automate Excel or Word. We **answer the question asked**, instead of writing random posts about things that are not. I'm going to point you **once again** to the [tour] and [help] pages. – Ken White May 26 '16 at 20:58
  • In addition, this answer contains an incorrect statement. *anything between a begin and an end; is respected as one line of code* is factually wrong. It's a single **block** of code, but it is in no way one **line of code**. At least your extraneous, off the subject *additional information* should be correct. – Ken White May 26 '16 at 22:09
  • key phrase here being "respected as" i did not say it "was" a line of code, stop making assumptions you clearly just go around trying to find something wrong with anyone that denies you. – Dominic May 26 '16 at 22:18
  • It is not **respected as** anything but a **block of code**. Saying anything else is incorrect. This is a technical site, and anything you say here is expected to be accurate and correct. For the 20th time, *take the [tour] and read the [help] pages*. If you insist on not doing so, you will continue to have issues here. We're not a chat room, discussion group, place for blogs or irrelevant posts, or anything else - it's a **technical site** where accuracy is expected. You've added nothing of value here by reposting what I've already written and adding wrong extraneous material. – Ken White May 26 '16 at 22:21
  • You are cluttering the comments. – Dominic May 26 '16 at 23:33
  • OK. If you insist. Don't say I didn't give you sufficient opportunity to correct your answer before downvoting. – Ken White May 26 '16 at 23:41