Help with Anagram Finder | C

Hello im currently stuck at the final step of Anagram Finder lesson.
If anyone can help that would be amazing!
This are the prompts to follow:

  1. Copy and paste the following starting code into your workspace:
#include<stdio.h>#include<string.h>int main() { }
  1. Create two integer arrays called counter1 and counter2 . Initialize both arrays with four zeros each.

  2. We will check if the following two strings are anagrams:

  • String 1: “dbb cccccaacb cdbababdcdcdab dcdad”
  • String 2: “bbbcc bdddccccad cdbbaaacaccdabdd”

Right under your counters, create two char arrays called s1 and s2 containing String 1 and String 2 respectively.

Counting the characters in String 1.

  1. First, create a for loop to loop through the string. Use strlen() to find the length of the string.

  2. We will now write the logic to determine the number of each character in String 1.

We will update counter1 in the following way:

  • If we encounter an ‘a’ we will increment counter1[0] by one.
  • If we encounter a ‘b’ we will increment counter1[1] by one.
  • If we encounter a ‘c’ we will increment counter1[2] by one.
  • If we encounter a ‘d’ we will increment counter1[3] by one.
  • If we encounter a space, we ignore it.

Implement this logic in the loop body.

Counting the characters in String 2.

  1. Loop through String 2 and update its counter ( counter2 ) accordingly.

Comparing the counts of both strings.

  1. We need a flag that we can use to determine if there is a mismatch in the two counters.

First, create an integer variable called flag and set it to 0 .

The flag variable maintains one of these states:

  • The flag will be set to zero if there is no mismatch in the counters.
  • The flag will be set to one if there is a mismatch in the counters.
  1. Create an empty for loop that you will use to loop through both counters. We will place logic in it in the next task.

  2. In the loop, change the flag variable’s value to 1 if a mismatch is encountered.

Well, are they anagrams?

  1. If the two strings are anagrams, print “Anagram!”. If they are not, print “Not Anagram!”

This is my code:

#include <stdio.h>
#include <string.h>

int main (){

//counters a, b, c, d
  int counter1 [] = {0,0,0,0};
  int counter2 [] = {0,0,0,0};

//strings to compare and verify
  char s1 [] = "dcba";
  char s2 [] = "aacd";

//flag for verification
int flag = 0;

 //verification process s1
  for (int i = 0; i < strlen(s1); i++){
    if (s1[i] == 'a'){
        counter1[0]++;
    }
    if (s1[i] == 'b'){
      counter1[1]++;
    }
    if (s1[i] == 'c'){
      counter1[2]++;
    }
    if (s1[i] == 'd'){
      counter1[3]++;
    }
    if (s1[i] == ' '){
      continue;
    }
  }
   //verification process s2
    for (int i = 0; i < strlen(s2); i++){
    if (s2[i] == 'a'){
        counter2[0]++;
      }
    if (s2[i] == 'b'){
      counter2[1]++;
      }
    if (s2[i] == 'c'){
      counter2[2]++;
      }
    if (s2[i] == 'd'){
      counter2[3]++;
      }
    if (s2[i] == ' '){
      continue;
      }
    }

    //check if they are anagrams
    for(int i = 0; i < 4; i++){
  if (counter1[i-1] == counter2[i-1]){
      flag == 0;
      }
      else {
        flag == 1;
      }
  }


if (flag == 0){
  printf("Anagram!\n");
}
  else {
    printf("Not Anagram!\n");
  }
}
1 Like

Hello there,
Not totally up on C, but I think this section may be causing some issues.
i is iterating 0 to 3, why are you subtracting 1 from it ?
You only need to be altering flag if you find a difference between the two.
You might want to check the difference between = and ==.

Have fun.

    for(int i = 0; i < 4; i++){
  if (counter1[i-1] == counter2[i-1]){
      flag == 0;
      }
      else {
        flag == 1;
      }
  }

2 Likes

Hey there :wave: There’s a few problems I see here.

As @pluginmaybe said above, why subtract one from i in your last loop? If you print it out you might not be getting the indexes you want.

Pay close attention to assignment = vs equality ==. In your last loop you have flag == 0; and flag == 1;. These are just boolean values, yes or no, 1 or 0. They’re not actually assigning to flag.

Lastly, your loop has no break condition. If the the first to chars are different, it tries to set flag to 0, but if the next to are the same flag just gets set back.

1 Like

Thank you so much for the answer! But I still dont get it (sorry! very very new here)
This is what i`ve done now:

#include <stdio.h>
#include <string.h>

int main (){

//counters a, b, c, d
  int counter1 [] = {0,0,0,0};
  int counter2 [] = {0,0,0,0};

//strings to compare and verify
  char s1 [] = "abcd";
  char s2 [] = "bcda";

//flag for verification
int flag = 0;

 //verification process s1
  for (int i = 0; i < strlen(s1); i++){
    if (s1[i] == 'a'){
        counter1[0]++;
    }
    if (s1[i] == 'b'){
      counter1[1]++;
    }
    if (s1[i] == 'c'){
      counter1[2]++;
    }
    if (s1[i] == 'd'){
      counter1[3]++;
    }
    if (s1[i] == ' '){
      continue;
    }
  }
   //verification process s2
    for (int i = 0; i < strlen(s2); i++){
    if (s2[i] == 'a'){
        counter2[0]++;
      }
    if (s2[i] == 'b'){
      counter2[1]++;
      }
    if (s2[i] == 'c'){
      counter2[2]++;
      }
    if (s2[i] == 'd'){
      counter2[3]++;
      }
    if (s2[i] == ' '){
      continue;
      }
    }

    //loop through the counters
    for(int i = 0; i < 4; i++){
      //check the values of the counter
      printf("%d\n",counter1[i]);
      printf("%d\n",counter2[i]);
    //check for inequality
  if (counter1[i] == counter2[i]){
      flag = 0;
      }
      else {
        flag = 1;
      }
  }
//print if it is anagram or not 
if (flag = 0){
  printf("Anagram!\n");
}
if (flag = 1) {
  printf("Not Anagram!\n");
  }

}
  


But the condition is still not checked properly, I dont understand how to use the break condition.
Its like literally im just trying random things to see if something works, im super stuck

Off the top of my head I only see one thing, and that’s that your for loop still has no break. In order to prevent the flag from being set back to 0, you need a break underneath of were it sets it to 1.

Would look something like this:

for (int i = 0; i < 4; i++) {
  if (counter1[i] == counter2[i]) {
    flag = 0;
  } else P
    flag = 1;
    break;
  } 
}

Now an interesting point here, is that you don’t really need a condition that would ever set flag to 0 since it’s initialized with a value of 0. Meaning we could simplify the condition to:

if (!(counter1[i] == counter2[i])) {
  flag = 1;
  break;
}
2 Likes

This is a slightly more advanced concept, but I think it’s something worth keeping in mind.
One of the most helpful things I’ve seen with anything indexed based, is to keep an eye out for areas were you already have the index you want to use.
In your code you store the number of each character at a spot in an array, then use a large chunk of ifs to increment each one.
Since a is at index 0, b at 1, and so on, you can say that the array is sorted. So if you could convert each character to an integer, you can use it as an index instead of dealing with all the ifs.
Well in C, and behind the scenes in most languages, characters are really just numbers that are displayed specially. C uses ASCII codes to store characters. And these have a range 0 - 127 (technically -128 to 127, but negative values aren’t normally used for characters.)

We can see this with:

#include <stdio.h>
#include <limits.h>

int main (){
  printf("min %d, max %d\n", CHAR_MIN, CHAR_MAX);
}

Now if look at an ASCII chart (or print the characters as integers) we see ‘A’-‘Z’ are grouped in order from 65 to 90:

printf("%d, %d\n", 'a', 'z'); // 65, 90

And ‘a’-‘z’ are grouped together 97 to 122:

printf("%d, %d\n", 'A', 'Z'); // 97, 122

Given they are ordered integer values, you could use them as an index for the array. We only need to deal with the offset, since the index starts at 0, and (assuming we’re sticking with lowercase) the ASCII codes start at 65. For that all we have to do is subtract 'a' from the char were working with.

Given we use the same variable names you use above:

for (int i = 0; i < strlen(s1); i++) {
  counter1[s1[i] - 'a']++;
}

No more bulky if/else if/else.

Of course, there’s the possibility for errors, given the arrays only four integers long, so we either need to

  1. expand the array to hold the whole alphabet.
  2. make sure our string only has characters a - d.

I’d go with the first option personally, but that’s really only necessary if you’re trying to make a full working program.

Note I’m not trying to take away from the project, just offer a little more information you can use later.

1 Like

That`s very very interesting, I am sure it will come in handy ! Thank you so much for taking the time to answer! I appreciate it very much, specially with the frustration of learning a new skill :sweat_smile:

1 Like

Maybe a little late but i wrote some code solving the same problem, i think so :sweat_smile:

#include<stdio.h>
#include<string.h>

int main() {
  int counter1[] = {0, 0, 0, 0};
  int counter2[] = {0, 0, 0, 0};
  char s1[] = "dbb cccccaacb cdbababdcdcdab dcdad";
  char s2[] = "bbbcc bdddccccad cdbbaaacaccdabdd";
  int flag = 0;

  for (int i = 0; i < strlen(s1); i++) {
    switch(s1[i]) {
      case 'a':
      counter1[0]++;
      break;
      case 'b':
      counter1[1]++;
      break;
      case 'c':
      counter1[2]++;
      break;
      case 'd':
      counter1[3]++;
      break;
      case ' ':
      break;
    }
    switch(s2[i]) {
      case 'a':
      counter2[0]++;
      break;
      case 'b':
      counter2[1]++;
      break;
      case 'c':
      counter2[2]++;
      break;
      case 'd':
      counter2[3]++;
      break;
      case ' ':
      break;
    }
    }
     for (int b = 0; b < sizeof(counter1) / sizeof(int); b++) {
      if (counter1[b] != counter2[b]) {
        flag = 1;
        break;
      }
        }

      
      if (flag == 1) {
        printf("Not Anagram!");
      }
      else {
        printf("Anagram!");
      }
    }
  
  
2 Likes