porównywanie dictionary - anagramy

0

elo wszystkim, mam problem. mam napisać program sprawdzający czy dwa słowa są anagramami. jednak moj program nie działa dla wyjątków taki jak np. 'kicjow' i 'ketrab'

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace anagram
{
    class Program
    {
        static void Main(string[] args)
        {
           

                Func<String, Dictionary<Char, Int32>> PoliczZnaki = (napis) =>
                {
                    var liczniki = new Dictionary<Char, Int32>();
                    foreach (var znak in napis)
                    {
                        if (Char.IsLetter(znak))
                        {
                            var litera = Char.ToLower(znak);
                            if (liczniki.ContainsKey(litera))
                            {
                                liczniki[litera] += 1;
                            }
                            else
                            {
                                liczniki[litera] = 1;
                            }
                        }
                    }
                    return liczniki;
                };



                Func<String, String, Boolean> JestAnagramem = (napis1, napis2) =>
                {

                    var slowko1 = PoliczZnaki(napis1);
                    var slowko2 = PoliczZnaki(napis2);

                    if (napis1.Length != napis2.Length)
                    {
                        return false;
                    }
                    else if (napis1 == napis2)
                    {
                        return true;
                    }
                        
                    else
                    {

                        
                        

                        foreach (var item1 in slowko1)
                        {
                            foreach (var item2 in slowko2)
                            {
                                if ((item1.Key == item2.Key) && (item1.Value ==  item2.Value))
                                    return true; // TO TA CZESC KODU JEST NA PEWNO ZŁA
                            }
                            
                            
                        }
                        
              
                    }
                    return false;

                };


                Console.WriteLine("wpisz dwa slowa, pierwsze:");
                Console.WriteLine();
                var slowo1 = Console.ReadLine();
                Console.WriteLine();
                Console.WriteLine("Drugie:");
                Console.WriteLine();
                var slowo2 = Console.ReadLine();
                Console.WriteLine();

                if (JestAnagramem(slowo1, slowo2))
                {
                    Console.WriteLine("jest anagramem!");
                }
                else
                {
                    Console.WriteLine("nie jest anagramem");
                }


                Console.ReadKey();

            


        }
    }
}
/* foreach (var item in slowko1)
                        {
                            foreach (var item2 in slowko2)
                            {
                                if ((item.Key == item2.Key) && (item.Value == item2.Value))
                                {
                                    return true;
                                }

                            }
}
*/ 

wiem, że zła jest ta część którą opisałem powyżej, jednak nie mam pomysłu na jej usprawnienie a przykłady które znalazłem na rożnych forach wykraczają daleko poza moje umiejętnosci.
z góry dziękuję za pomoc!

0
int cmp(char*a,char*b){return *a<*b;}
 
int czyAnagramy(char a[], char b[]){
        qsort(a,strlen(a),1,cmp);
        qsort(b,strlen(b),1,cmp);
        return strcmp(a,b)==0;}
0

@up w O(nlogn)? Nieoptymalnie :P Szybciej będzie zrobić dwie tablice do zliczania ile i które symbole wystąpiły, a potem przelecieć po nich i sprawdzić czy tablice wynikowe są takie same. W ten sposób dostajemy rozwiązanie w O(n) a pamięciowo nadal mamy O(1) (bo ilość elementów w tablicach pomocniczych nie zależy w żaden sposób od długości wejścia).

0
int czyAnagram(char*a, char*b){
    int t[256]={0};
    for( i=0; i<len(a); i++ ) t[a[i]]++;
    for( i=0; i<len(b); i++ ) t[b[i]]--;
    for( j=i=0; i<256; i++ ) j|=t[i];
    return j==0;}

dłuższe o jedną linijkę :-)

0

tu pewnie nie tyle chodzi o rozwiązanie, co o "rozwiązanie przy pomocy" klas i dykcjonarzy
dykcjonarz powinien być jeden, jednym stringiem dodajesz/inkrementujesz, a drugim dekrementujesz/usuwasz.
pomijasz porównywanie string==string, pomijasz porównywanie długości to się załatwi samo
a co do błędu
powiedzmy że zgadzają się dla pierwszego znaku, przerywasz i krzyczysz OK bez sprawdzania reszty
a powinieneś przerwać gdy znajdziesz różnicę zwracasz "false", dopiero po zakończeniu pętli możesz powiedzieć "true"
zobacz: "prawa De Morgana"

1 użytkowników online, w tym zalogowanych: 0, gości: 1