简体   繁体   中英

Unique correspondence for characters in C#


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.

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

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);

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 ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM