简体   繁体   中英

Compare lexicographically two char arrays

Can you help with this?

I need to compare lexicographically two arrays: if one of them is shorter than other, it is lexicographically first. If their length are same, they had to be compared element by element. If an element is before the other in the alphabet, this array is lexicographically first.

Here is my code:

using System;

internal class CompareTwoCharArraysLexicographically
{
    private static void Main()
    {
       char[] firstArray = {'a', 'b', 'c', 'z'};
       int firstArrayLength = firstArray.Length;
       char[] secondArray = {'a', 'b', 'c', 'd'};
       int secondArrayLength = secondArray.Length;
       int length = Math.Min(firstArray.Length, secondArray.Length);

       if (firstArray.Length > secondArray.Length)
       {
          Console.WriteLine("Second array is earlier.");
       }

       else if (firstArray.Length == secondArray.Length)
       {
          for (int i = 0; i < length; i++)
          {
              if (firstArray[i] > secondArray[i])
              {
                  Console.WriteLine("2 array is earlier.");
                  break;
              }
              else if (secondArray[i] > firstArray[i])
              {
                  Console.WriteLine("1 array is earlier."); 
                  break;
              }
              else
              {
                  Console.WriteLine("Two arrays are equal.");
              }
          }
       }
       else
       {
          Console.WriteLine("First array is earlier.");
       }
    }
}

How I can avoid three time repeated message "Two arrays are equal."?

Yet another structured way to do it:

class LexicographicCharArrayComparer : Comparer<char[]>
{
    public override int Compare(char[] x, char[] y)
    {
        if (x == null || y == null)
            return Default.Compare(x, y);

        int lengthComp = x.Length.CompareTo(y.Length);
        if (lengthComp != 0)
            return lengthComp;

        return StringComparer.Ordinal.Compare(new string(x), new string(y));
    }
}

Usage:

        char[] firstArray = { 'a', 'b', 'c', 'z', };
        char[] secondArray = { 'a', 'b', 'c', 'd', };

        var comparer = new LexicographicCharArrayComparer();
        var result = comparer.Compare(firstArray, secondArray);
        if (result < 0)
            Console.WriteLine("1st array is earlier");
        else if (result == 0)
            Console.WriteLine("The two arrays are equal");
        else
            Console.WriteLine("2nd array is earlier");

Your own approach can be repaired, of course. Correct the middle block to something like:

   else if (firstArray.Length == secondArray.Length)
   {
      bool resolved = false;
      for (int i = 0; i < length; i++)
      {
          if (firstArray[i] > secondArray[i])
          {
              Console.WriteLine("2 array is earlier.");
              resolved = true;
              break;
          }
          if (secondArray[i] > firstArray[i])
          {
              Console.WriteLine("1 array is earlier."); 
              resolved = true;
              break;
          }
      }
      if (!resolved)
      {
          Console.WriteLine("Two arrays are equal.");
      }
   }

I think you will need to use a tracking variable to know whether or not the arrays are equal. Currently you are saying they are equal each time two items in the same index are equal. Instead, consider the following code:

else if (firstArray.Length == secondArray.Length)
{
    var largerArray = 0;

    // Compare each item in the array
    for (int i = 0; i < length; i++)
    {
        // As soon as two items are not equal, set the comparison value and break
        if (firstArray[i] > secondArray[i])
        {
            largerArray = 1;
            break;
        }
        else if (secondArray[i] > firstArray[i])
        {
            largerArray = 2
            break;
        }
    }

    // Check the largerArray value. If it was never changed, the arrays are equal
    // Otherwise, display a message based on the value of the largerArray.
    if (largerArray == 0)
    {
        Console.WriteLine("Two arrays are equal.");
    }
    else
    {
        Console.WriteLine("{0} array is earlier.", largerArray); 
    }
}

Here is my suggestion:

        Console.Write("Enter a positive number for length of the first array: ");
        int n = int.Parse(Console.ReadLine());
        Console.Write("Enter a positive number for length of the second array: ");
        int m = int.Parse(Console.ReadLine());

        // Declare and create the arrays
        char[] firstArray = new char[n];
        char[] secondArray = new char[m];

        Console.WriteLine("Enter values of the arrays: ");
        for (int i = 0; i <  firstArray.Length; i++)
        {
            firstArray[i] = char.Parse(Console.ReadLine());
        }
        Console.WriteLine();

        for (int i = 0; i < m; i++)
        {
            secondArray[i] = char.Parse(Console.ReadLine());
        }
        Console.WriteLine();

        // Print them on the console
        for (int i = 0; i < n; i++)
        {
            Console.Write(" " + firstArray[i]);
        }            
        Console.WriteLine();

        for (int i = 0; i < m; i++)
        {
            Console.Write(" " + secondArray[i]);
        }            
        Console.WriteLine();

        int minLength = Math.Min(firstArray.Length, secondArray.Length);
        bool equalValues = true;

        // Search which of the arrays is lexicographically earlier
            for (int i = 0; i < minLength; i++)
            {
                if (firstArray[i] == secondArray[i])
                {
                    continue;
                }
                else if (firstArray[i] < secondArray[i])
                {
                    Console.WriteLine("The first array is earlier.");
                    break;
                }
                else if (firstArray[i] > secondArray[i])
                {
                    Console.WriteLine("The second array is earlier.");
                    break;
                }
            }
            for (int i = 0; i < minLength; i++)
            {
                if (firstArray[i] != secondArray[i])
                {
                    equalValues = false;
                }
            }
            // This is to indicate the values of the two arrays till the element of index minLength-1 are equal
            for (int i = 0; i < minLength; i++)
            {
                if (equalValues && n < m)
                {
                    Console.WriteLine("The first array is earlier.");
                    break;
                }   
                else if (equalValues && n > m)
                {
                    Console.WriteLine("The second array is earlier.");
                    break;
                }
                else if (equalValues && n == m)
                {
                    Console.WriteLine("The two arrays aree equal.");
                    break;
                }          
            }                          

Here is a relatively simple implementation using the sums of the ASCII values of the array characters as a lexicographical comparison criteria:

/*  Method: compareLexicographically(a, b);
    Compare lexicographically the two arrays passed as parameters and print result.
    Comparison criteria:
    1. Arrays lengths.
    2. Accumulated ASCII values of the array characters. 
*/
static void compareLexicographically(char[] a, char[] b)
{
    if (a.Length == b.Length) // same lengths
    {
        int suma = 0;
        int sumb = 0;
        for (int i = 0; i < a.Length; i++)
        {
            suma += a[i];
            sumb += b[i];
        }

        if (suma == sumb)
        {
            Console.WriteLine("Two arrays are lexicographically equal.\n");
        }
        else
        {
            if (suma < sumb)
            {
               Console.WriteLine("First array lexicographically smaller than second.\n");
            }
            else
            {
                Console.WriteLine("First array lexicographically greater than second.\n");
            }
        }
    }
    else  // different lengths
    {
        if (a.Length < b.Length)
        {
            Console.WriteLine("First array lexicographically smaller than second.\n");
        }
        else
        {
            Console.WriteLine("First array lexicographically greater than second.\n");
        }
    }
}

I think that this fixes your problem :) Hope I helped you as well u helped me find an answer of an exercise

using System;

internal class CompareTwoCharArraysLexicographically
{
    private static void Main()
    {
        char[] firstArray = { 'a', 'b', 'c', 'z' };
        int firstArrayLength = firstArray.Length;
        char[] secondArray = { 'a', 'b', 'c', 'd' };
        int secondArrayLength = secondArray.Length;
        int length = Math.Min(firstArray.Length, secondArray.Length);
        bool same = false;

        if (firstArray.Length > secondArray.Length)
        {
            Console.WriteLine("Second array is earlier.");
        }

        else if (firstArray.Length == secondArray.Length)
        {
            for (int i = 0; i < length; i++)
            {
                if (firstArray[i] != secondArray[i])
                {
                    same = false;


                    if (firstArray[i] > secondArray[i])
                    {
                        Console.Clear();
                        Console.WriteLine("2 array is earlier.");
                        break;
                    }
                    if (secondArray[i] > firstArray[i])
                    {
                        Console.Clear();
                        Console.WriteLine("1 array is earlier.");
                        break;
                    }

                }



                else same = true;


                if (same == true)
                {
                    Console.Clear();
                    Console.WriteLine("Two arrays are equal."); 

                }

                else
                {
                    Console.WriteLine("First array is earlier.");
                }
            }
        }
    }
}

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