0

I have to make an algorithm who compares two strings and returns a boolean.

it is true if all the letters of string a are present in string b.

for example "romain" and "marion" returns true.

"world" and "dlrow" returns true.

my code works only in case there is no duplicate and I don't understand why. Thank you for your help.

        string a = @"aka";
        string b = @"aka";

        bool istwin(string x, string y)
        {
            int compteur = 0;
            if (x.Count() == y.Count())
            {
                int index = x.Count();

                for (int i = 0; i < index; i++)
                {
                    for (int z = 0; z < index; z++)
                    {
                        Console.WriteLine(x[z] + "  comparé  à " + y[i]+"indexs : "+z+" ,  "+i);
                        if (x[z] == y[i])
                        {
                            compteur++;
                        }                         
                    }

                }
                Console.WriteLine();
                Console.WriteLine(compteur);
                if (compteur == index)
                  {
                     return true;
                  }
                   else
                   {
                    return false;
                   }

            }
            else
            {
                return false;
            }

        }

        //istwin(a, b);
        Console.WriteLine(istwin(a, b));
    }
3
  • You likely need some sort of Enumerable.Intersect … could you please edit post to clarify expectations - what results should be for following pairs: {"aaa", "a"}, {"a", "aaa"}, {"a", "abc"}? Commented Mar 24, 2020 at 21:01
  • hum false, false and false Commented Mar 24, 2020 at 21:04
  • 1
    Can you reproduce the exact specification of the function that you need to write? Based on your description, which says "it is true if all the letters of string a are present in string b", those would all have to be true. For example, every 'a' in "aaa" is present in "a". Commented Mar 24, 2020 at 21:13

2 Answers 2

3

You can simplify your algorithm using Except method from System.Linq. Since string in C# represents a readonly sequence of characters, you can get a difference between two sequences and check its count

bool istwin(string x, string y)
{
    return x.Except(y).Count() == 0;
}

It'll return true for example strings

Console.WriteLine(istwin("aka", "aka")); //returns true
Console.WriteLine(istwin("world", "dlrow")); //returns true
Console.WriteLine(istwin("romain", "marion")); //returns true

To cover the case, when "a" and "aaa" strings should return false (according to comments) you can add an additional check for length of strings, like

bool istwin(string x, string y)
{
    return x.Length == y.Length && x.Except(y).Count() == 0;
}

Result will be the following

Console.WriteLine(istwin("a", "aaa")); //returns false
Console.WriteLine(istwin("a", "abc")); //returns false
Sign up to request clarification or add additional context in comments.

3 Comments

Note that this does not satisfy OP's comment {"aaa", "a"} -> false, {"a", "aaa"} -> false, {"a", "abc"} -> false... Still need to sort out what they are actually looking for.
thank you, i did not now this method, thats great !
This still fails for "aka" and "akb", because they have the same length and all characters will be removed from the first string.
3

Others have shown answers using LINQ. This is an advanced programming concept. When learning C#, you might want to do this without LINQ. Below are two possible algorithms.


The problem in your code is that (in the example with the 2 "aka") you count the first "a" twice in the second "aka" and the second "a" as well.

With "aka" and "akb", this would give you the right count, because it would find each letter of the first word in the second one once. Which is wrong either.


One solution would be to remove each letter from the second word, once found. We do this simply by replacing the letter with a NUL character:

private static bool IsAnagramRemove(string s, string t)
{
    if (s.Length != t.Length) {
        return false;
    }

    // Convert second word to char array, so we can remove matched letters.
    char[] tChar = t.ToCharArray();

    int count = 0;
    for (int i = 0; i < s.Length; i++) {
        for (int j = 0; j < tChar.Length; j++) {
            if (s[i] == tChar[j]) {
                tChar[j] = (char)0; // Remove (well.., replace by 0).
                count++;
                break; // Leave the inner loop.
            }
        }
    }
    return count == s.Length;
}

Note that you can replace this

if (compteur == index)
{
    return true;
}
else
{
    return false;
}

by this

return compteur == index;

Because the expression compteur == index yields a boolean value representing the outcome of the comparision.


Another possibility is to first sort the letters in both words, so that you can then compare the letters at the same position in both words:

private static bool IsAnagramSort(string s, string t)
{
    if (s.Length != t.Length) {
        return false;
    }
    char[] a = s.ToCharArray();
    char[] b = t.ToCharArray();
    Array.Sort(a);
    Array.Sort(b);
    for (int i = 0; i < a.Length; i++) {
        if (a[i] != b[i]) {
            return false;
        }
    }
    return true;
}

No need to count here. If you reach the end of the loop, it means that we have found an anagram.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.