Home > database >  Unique correspondence for characters in C#
Unique correspondence for characters in C#

Time:10-15


I'm new to programming and I got really stuck on an exercise.
I need to determine whether each character in the first string can be uniquely replaced by a character in the second string. Both strings are equal in length.
For example, "aabc ea" and "ddtf hd" , the result needs to be:
True
a => d
b => t
c => f
  =>  
e => h

If I have for example "abac ea" and "ddtf hd" , the result needs to be:

False

Since "abac ea" and "ddt hd" don't have an unique replacement.

This is my Code:

using System;

namespace UniqueStrings
{
    class Program
    {
        static void Main(string[] args)
        {
   
            string firstPhrase = Console.ReadLine();
            string secondPhrase = Console.ReadLine();

            bool result = false;
            int charsCount = 0;

            char[] firstPhraseChars = new char[firstPhrase.Length];
            char[] secondPhraseChars = new char[secondPhrase.Length];

            if (firstPhrase.Length != secondPhrase.Length)
            {
                result = false;
            }

            for (int i = 0; i < firstPhrase.Length; i  )
            {
                if (firstPhrase[i] == firstPhraseChars[i])
                {
                    firstPhraseChars[i] = firstPhrase[i];
                    secondPhraseChars[i] = secondPhrase[i];
                }

                for (int j = 0; j < secondPhrase.Length; j  )
                {
                    if (secondPhrase[j] == secondPhraseChars[j])

                    {
                        firstPhraseChars[j] = firstPhrase[j];
                        secondPhraseChars[j] = secondPhrase[j];
                        result = false;

                    }
                    else
                    {
                        result = true;
                    }
                }
                

            }

            for (int i = 0; i < firstPhrase.Length; i  )
            {
                if (result == false)
                {
                    firstPhraseChars[charsCount] = firstPhrase[i];
                    secondPhraseChars[charsCount] = secondPhrase[i];
                    charsCount  ;
                }
            }

                if (result == false)
                Console.WriteLine(result);
            else
            {
                Console.WriteLine(result);
                for (int i = 0; i < firstPhrase.Length; i  )
                {
                    Console.WriteLine(firstPhrase[i]   " => "   secondPhrase[i]);
                }
            }
            Console.Read();
        }
    }
}

Can someone please help me understand what I'm doing wrong? I have no idea anymore and I feel like this code will never work. There needs to be some solution to this, which I'm not understanding.

I'm not supposed to use LINQ, list or dictionary, only System.
If anyone has other questions, feel free to ask.

CodePudding user response:

exemple of non-optimized solution

using System;

namespace UniqueStrings
{
    class Program
    {
        static bool CheckStringSimilarity(string firstPhrase, string secondPhrase)
        {
            if (firstPhrase.Length != secondPhrase.Length)
            {
                return false;
            }

            var length = firstPhrase.Length;
            for (var i =0; i<length; i  )
            {
                for(var j=0; j<length; j   )
                {
                    if((firstPhrase[i] == firstPhrase[j]) && (secondPhrase[i] != secondPhrase[j]))
                    {
                       return false;                       
                    }
                    if((firstPhrase[i] != firstPhrase[j]) && (secondPhrase[i] == secondPhrase[j]))
                    {
                       return false;                       
                    }                   
                }
            }

            return true;
        }
        static void Main(string[] args)
        {

            Console.WriteLine($"CheckStringSimilarity('aaa','bbb') = {CheckStringSimilarity("aaa", "bbb")}");
            Console.WriteLine($"CheckStringSimilarity('aaab','bbbc') = {CheckStringSimilarity("aaab", "bbbc")}");
            Console.WriteLine($"CheckStringSimilarity('rrt','aze') = {CheckStringSimilarity("rrt", "aze")}");
            Console.WriteLine($"CheckStringSimilarity('rrt dd','aad aa') = {CheckStringSimilarity("rrt dd", "aad aa")}");
        }
    }
}

DEMO

CodePudding user response:

In your first for loop the result will always be true since both if statements will always return false. When the if statements compare their values "firstPhraseChars[i]" and "secondPhraseChars[j]" are always empty since you never put anything into these arrays before the comparison.

Hope this helps without giving away too much ;)

CodePudding user response:

You can look for a counter example: if you've found it, correspondent doesn't exist:

private static bool HasCorrespondence(string left, string right) {
  if (left == null)
    return right == null;
  if (right == null)
    return false;

  if (left.Length != right.Length)
    return false;

  // known correspondence
  Dictionary<char, char> correspondence = new Dictionary<char, char>();

  for (int i = 0; i < left.Length;   i)
    if (correspondence.TryGetValue(left[i], out char expected)) {
      // counter example: we want expected, but have right[i]
      if (expected != right[i])
        return false;
    }
    else
      // we have nothing for left[i], so we can add (left[i], right[i]) pair   
      correspondence.Add(left[i], right[i]);

  // no counter example exists, return true
  return true;
}

If Dictionary is prohibited, you can emulate it with help of array:

private static bool HasCorrespondence(string left, string right) {
  if (left == null)
    return right == null;
  if (right == null)
    return false;

  if (left.Length != right.Length)
    return false;

  int[] correspondence = new int[char.MaxValue];

  for (int i = 0; i < left.Length;   i)
    if (correspondence[left[i]] != 0) {
      if (correspondence[left[i]] != right[i])
        return false;
    }
    else
      correspondence[left[i]] = right[i];

  return true;
}

If you are looking for one to one correspondence, you can just check twice"

private static bool HasOneToOne(string left, string right) =>
  HasCorrespondence(left, right) &&
  HasCorrespondence(right, left);
  • Related