Fethi Tekyaygil
Fethi Tekyaygil

Reputation: 343

C# Anagram Checker With LinkedList

I'm trying to check if two words are anagram and trying to do this with LinkedList.To do that,first,I created a class named LinkedList:

class LinkedList
 {
    private Node head;
    private int count;

    public LinkedList()
    {
        this.head = null;
        this.count = 0;
    }

    public bool Empty
    {
        get { return this.count == 0; }
    }

    public int Count
    {
        get { return this.count; }
    }

    public object this[int index]
    {
        get { return this.Get(index); }
    }

    public object Add(int index,object o)
    {
        if (index < 0)
        {
            throw new ArgumentOutOfRangeException("Index - " + index); //if index is less than 0 throw an error message
        }
        if (index > count)  // if size exceeds the limit of the list the item will be added to the last line of the list.
        {
            index = count;
        }

        Node current = this.head;

        if(this.Empty || index== 0)
        {
            this.head = new Node(o, this.head);
        }
        else
        {
            for(int i = 0; i < index - 1; i++)
            {
                current = current.Next;
            }

            current.Next = new Node(o, current.Next);
        }
        count++;

        return o;


    }

    public object Add(Object o)
    {
        return this.Add(count, o);
    }

    public object Remove(int index)
    {
        if (index < 0)
        {
            throw new ArgumentOutOfRangeException("Index - " + index);
        }
        if (this.Empty)
        {
            return null;
        }

        if (index >= this.count)
        {
            index = count-1;
        }

        Node current = this.head;
        object result = null;


        if (index == 0)
        {
            result = current.Data;   //gets the first node
            this.head = current.Next;  //makes 2nd node to the first node 
        }
        else
        {
            for(int i = 0; i < index - 1; i++)
            {
                result = current.Next.Data;
            }
            result = current.Next;
            current.Next = current.Next.Next;
        }
        count--;

        return result;
    }
    public int IndexOf(object o)
    {
        Node current = this.head;


        for(int i = 0; i < this.count; i++)
        {
            if (current.Data.Equals(o))
            {
                return i;
            }
            current = current.Next;
        }
        return -1;
    }

    public bool Contains(object o)
    {
        return this.IndexOf(o) >= 0; //if list contains object it returns bigger value than -1 and also 0.
    }

    public object Get(int index)
    {
        if(index < 0)
        {
            throw new ArgumentOutOfRangeException("Index - " + index);
        }

        if (this.Empty)
        {
            return null;
        }

        if(index >= this.count)
        {
            index = this.count-1;
        }

        Node current = this.head;


        for(int i=0;i< index; i++)
        {
            current = current.Next;
        }

        return current.Data;
    }
}

And another class named "Node":

class Node
{
    private object data;
    private Node next;

    public Node(object data,Node next) //constructor
    {
        this.data = data;
        this.next = next;
    }

    public object Data
    {
        get { return this.data; }
        set { this.data = value; }
    }
    public Node Next
    {
        get { return this.next; }
        set { this.next = value; }
    }
}

And in main program,I created two objects from linkedlist class and read two strings from user and added the words' chars to the linked list.And compared the chars and if they found they'll be deleted from linkedlist,increases the counter and so on.If counter equals to the list1's number ofelements then they are anagrams if not the words are not anagrams.Here's my main program code:

class Program
{

    static void Main(string[] args)
    {


        int counter = 0;
        String word1, word2;
        Console.WriteLine("Welcome to Anagram Checker!\nPlease enter your first word:");
        word1 = Console.ReadLine();
        Console.WriteLine("\nPlease enter the second word:");
        word2 = Console.ReadLine();

        int result = AnagramChecker(word1, word2, counter);

        if (result == 1)
        {
            Console.WriteLine("These words are anagram");
        }
        if (result == 0)
        {
            Console.WriteLine("The words are not anagrams");
        }

        Console.ReadLine();
    }

    public static int AnagramChecker(String word1, String word2, int counter)
    {
        char[] ArrayWord1 = word1.ToCharArray();
        char[] ArrayWord2 = word2.ToCharArray();

        LinkedList list1 = new LinkedList();
        LinkedList list2 = new LinkedList();


        for (int i = 0; i < ArrayWord1.Length; i++) //Adds char of word1 to the list
        {
            list1.Add(i,ArrayWord1[i]);
        }


        for (int j = 0; j < ArrayWord2.Length; j++) //Adds char of word2 to the list
        {
            list2.Add(j,ArrayWord2[j]);
        }

        int max;
        if (list1.Count >= list2.Count)
        {
            max = list1.Count;
        }
        if (list2.Count > list1.Count)
        {
            max = list2.Count;
        }

        for (int i = 0; i < list1.Count; i++)
        {

            if (list2.Contains(list1[i]) && list1.Contains(list2[i]))
            {
                list1.Remove(i);
                list2.Remove(list2.IndexOf(list1[i]));

                counter++;
            }
        }

        Console.WriteLine(counter);

        if (counter == word1.Length || counter == word2.Length)
        {
            return 1;
        }

        else
            return 0;
    }
}

When I'm entering different words I get different results.The output examples are below.What do I do wrong?

Outputs:

1-)

Output 1 and it's error

2-)

Output 2 and it's error

Thanks for your kind helps.

Upvotes: 3

Views: 373

Answers (3)

Fethi Tekyaygil
Fethi Tekyaygil

Reputation: 343

Your answers are:

int[] sayilar1 = new int[150];
    int[] sayilar2 = new int[150];

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        var rand = new Random();

        for (int i = 0; i < sayilar1.Length; i++)
        {
            sayilar1[i] = rand.Next();
            sayilar2[i] = rand.Next();

            lvNumbers.Items.Add(sayilar1[i].ToString());
            lvNumbers.Items.Add(sayilar2[i].ToString());
        }



    }

    private void btnShuffle_Click(object sender, EventArgs e)
    {
        int[]newArray=BubbleSort();

        for (int i = 0; i < newArray.Count(); i++)
        {
            lvSorted.Items.Add(newArray[i].ToString());
        }
    }

    private int[] BubbleSort()
    {
        int temp = 0;
        int[] newArray = new int[300];
        for (int i = 0; i < 300; i++)
        {
            if (i < 150)
            {
                newArray[i] = sayilar1[i];
            }
            if (i >= 150)
                newArray[i] = sayilar2[i - 150];
        }

        for (int i = 0; i < newArray.Length; i++)
        {
            for (int sort = 0; sort < newArray.Length - 1; sort++)
            {
                if (newArray[sort] > newArray[sort + 1])
                {
                    temp = newArray[sort + 1];
                    newArray[sort + 1] = newArray[sort];
                    newArray[sort] = temp;
                }
            }
        }
        return newArray;
    }
}

2.

     private void btnTek_Click(object sender, EventArgs e)
    {
        lvFiltered.Items.Clear();

        string[] sayilar = tbSayilar.Text.Split('\n');
        int[] array = new int[sayilar.Length];

        for (int i = 0; i < sayilar.Length; i++)
        {
            array[i] = int.Parse(sayilar[i]);
        }


        List<int> ayiklanmisSayilar = TekCiftAyir(array, "T");

        for (int i = 0; i < ayiklanmisSayilar.Count; i++)
        {
            lvFiltered.Items.Add(ayiklanmisSayilar[i].ToString());
        }
    }
    private void btnCift_Click(object sender, EventArgs e)
    {
        lvFiltered.Items.Clear();

        string[] sayilar = tbSayilar.Text.Split('\n');
        int[] array = new int[sayilar.Length];

        for (int i = 0; i < sayilar.Length; i++)
        {
            array[i] = int.Parse(sayilar[i]);
        }
        List<int> ayiklanmisSayilar = TekCiftAyir(array, "C");

        for (int i = 0; i < ayiklanmisSayilar.Count; i++)
        {
            lvFiltered.Items.Add(ayiklanmisSayilar[i].ToString());
        }
    }

    private List<int> TekCiftAyir(int[] array, string TC)
    {
        List<int> ayiklanmisSayilar = new List<int>();

        if (TC == "T")
        {
            for (int i = 0; i < array.Length; i++)
            {
                if (array[i] % 2 == 1)
                {
                    ayiklanmisSayilar.Add(array[i]);
                }
            }
        }
        if (TC == "C")
        {
            for (int i = 0; i < array.Length; i++)
            {
                if (array[i] % 2 == 0)
                {
                    ayiklanmisSayilar.Add(array[i]);
                }
            }
        }
        return ayiklanmisSayilar;
    }


    }

Upvotes: 0

Fethi Tekyaygil
Fethi Tekyaygil

Reputation: 343

I fixed the problem,I just modified the if statement which checks if they're anagram or not:

for (int i = 0; i < list1.Count; i++)
        {

            if (list2.Contains(list1[i]))
            {
                list1.Remove(i);
               // list2.Remove(list2.IndexOf(list1[i]));

                i--;
                counter++;

            }

Thanks all of you for your helps :)

Upvotes: 1

Thomas Ayoub
Thomas Ayoub

Reputation: 29471

If you're just looking to find if words are anagrams, you can use this method:

private static bool areAnagrams(string word1, string word2)
{
    List<char> w1 = word1.OrderBy(c => c).ToList();
    List<char> w2 = word2.OrderBy(c => c).ToList();

    return !w1.Where((t, i) => t != w2[i]).Any();
}

Which create two lists ordered with the words chars, then compare both.


More readable equivalent:

private static bool areAnagrams(string word1, string word2)
{
    List<char> w1 = word1.OrderBy(c => c).ToList();
    List<char> w2 = word2.OrderBy(c => c).ToList();

    if (w1.Count != w2.Count)
        return false;

    for (int i = 0; i < w1.Count; i++)
    {
        if (w1[i] != w2[i])
            return false;
    }
    return true;
}

Upvotes: 2

Related Questions