c# Alpha Telephone Number Translator

前端 未结 5 1549
忘掉有多难
忘掉有多难 2021-01-28 01:35

I have a homework assignment where the program will accept any phone number in the format similar to 555-GET-FOOD. The task is to map the alphabetic letters to numbers and tran

相关标签:
5条回答
  • 2021-01-28 01:55

    Here are some options for simple logic to process phone numbers as described. Note that while a novel approach, using an Enum to map letters to integer values somewhat complicates the process more than it needed to be.

    Even though other methods exist for specifically mapping alpha-numeric phone numbers (think Regex) if you do ever need to iterate or process using Enum Names and Values then I hope you find these algorithms useful.

    A dictionary would have been far simpler as a mapping construct to process from.

    Regex where the LetterNumber mapping is defined in the expression would have been superior again.

    /// <summary>
    /// Iterates through the characters in a phone number converting letters to digits.
    /// </summary>
    /// <remarks>Uses StringBuilder to build the output iteratively, this method does not attempt to validate the number passed in</remarks>
    /// <see cref="LetterNumber"/>
    /// <param name="str">Phone number to parse</param>
    /// <returns>Phone number output where letters have been parsed into their digit values</returns>
    private string ParsePhoneNumber_StringBuilder(string str)
    {
        StringBuilder output = new StringBuilder();
        foreach (char ch in str.ToCharArray())
        {
            // Convert each letter to it's numeric value as defined in the LetterNumber enum
            // Dashes are not letters so they will get passed through
            if (char.IsLetter(ch))
            {
                if (Enum.IsDefined(typeof(LetterNumber), ch.ToString()))
                {
                    LetterNumber letterNumber = (LetterNumber)Enum.Parse(typeof(LetterNumber), ch.ToString(), true);
                    output.Append((int)letterNumber);
                }
            }
            else
                output.Append(ch);
        }
        return output.ToString();
    }
    
    /// <summary>
    /// Uses Linq to parse the characters in a phone number converting letters to digits.
    /// </summary>
    /// <remarks>This method does not attempt to validate the number passed in</remarks>
    /// <see cref="LetterNumber"/>
    /// <param name="str">Phone number to parse</param>
    /// <returns>Phone number output where letters have been parsed into their digit values</returns>
    private string ParsePhoneNumber_Linq(string str)
    {
        return String.Join("", str.Select(c => char.IsLetter(c) ? ((int)((LetterNumber)Enum.Parse(typeof(LetterNumber), c.ToString(), true))).ToString() : c.ToString()));
    }
    
    /// <summary>
    /// Iterates through the LetterNumber values and replaces values found in the passed in phone number.
    /// </summary>
    /// <remarks>Iterates through Enum Names and applied String.Replace</remarks>
    /// <see cref="LetterNumber"/>
    /// <param name="str">Phone number to parse</param>
    /// <returns>Phone number output where letters have been parsed into their digit values</returns>
    private string ParsePhoneNumber_Replacement(string str)
    {
        str = str.ToUpper(); // we will compare all letters in upper case
        foreach (string letter in Enum.GetNames(typeof(LetterNumber)))
            str = str.Replace(letter.ToUpper(), ((int)((LetterNumber)Enum.Parse(typeof(LetterNumber), letter))).ToString());
        return str;
    }
    
    0 讨论(0)
  • 2021-01-28 02:00

    It looks like you did attempt to use TryParse:

    //ch = Enum.TryParse(AlphaNumber);

    That is the method that you probably want to use. But there are a number of problems with it in that form, which probably gave you errors as you mentioned.

    The parameters this method expects are a string (which matches the enumerated constant, or name from the enum) and an out parameter of the type of the enum you want to parse. The method return a bool.

    If the TryParse is successful then the method returns TRUE with the corresponding value from the enum set in the out parameter.

    This code should allow you to get the result you want as an int using your variable ch as a string for the input to parse:

    AlphaNumber parsedCh;
    int? chValue = null;
    
    if (Enum.TryParse(ch.ToString().ToUpper(), out parsedCh)) 
    {
        chValue = (int)parsedCh;
        Console.WriteLine(chValue); 
    }
    
    0 讨论(0)
  • 2021-01-28 02:09

    Drop the enum and the switch, and instead do a lookup against a map. I have created a .NET Fiddle that demonstrates this working as desired here.

    But if using a Dictionary<char, char> is for some odd reason out of question, then I suppose you could use this version -- in which I use the enum. It is just a lot more work and the more moving parts you have the harder it is to maintain.

    In C# the type enum inherits from int by default, but you can specify various other numeric types -- like byte or long, etc... One of the key takeaways is the concept of boxing/unboxing and casting/converting from one type to another. If you have an enum defined as enum Foo { Bar = 63 } and you try to cast it to a char what would you expect to get?

    This actually would result in the char ? -- take a look at the ASCII table and the find the DEC for 63 and look at what it maps to for the Char column.

    The issue is fixed with this crazy complicated mess:

        public enum AlphaNumber
        { 
            A=2, B=2, C=2, D=3, E=3, F=3, G=4, H=4, I=4, J=5, K=5, L=5, 
            M=6, N=6, O=6, P=7, Q=7, R=7, S=8, T=8, U=8, V=9, W=9, X=9, Y=9, Z=9
        }
    
        public static class PhoneNumber
        {
            public static char ParseInput(char input)
            {
                if (input == '-' || char.IsDigit(input))
                {
                    return input;
                }
    
                if (char.IsLetter(input))
                {
                    var num = (AlphaNumber)(Enum.Parse(typeof(AlphaNumber), (char.IsLower(input) ? char.ToUpperInvariant(input) : input).ToString()));
                    return ((int)num).ToString()[0];
                }
    
                return '\0';
            }
        }
    
    0 讨论(0)
  • 2021-01-28 02:16
    using System;
    
    public class Program
    {
        public static void Main()
        {
            Console.WriteLine(AlphaPhoneToNumber("555-GET-FOOD"));
        }
    
        public static string AlphaPhoneToNumber(string val){
            //strings are immutable so let's get the array version of the value
            var phoneNumberArr = val.ToCharArray();
            for(int i = 0; i < val.Length; i++){
                phoneNumberArr[i] = AlphaPhoneCharToNumber(phoneNumberArr[i]);
            }
            return new string(phoneNumberArr);
        }
    
        public static char AlphaPhoneCharToNumber(char val){
            switch(val){
                case 'A':
                case 'B':
                case 'C':
                    return '2';
                case 'D':
                case 'E':
                case 'F':
                    return '3';
                case 'G':
                case 'H':
                case 'I':
                    return '4';
                case 'J':
                case 'K':
                case 'L':
                    return '5';
                case 'M':
                case 'N':
                case 'O':
                    return '6';
                case 'P':
                case 'Q':
                case 'R':
                    return '7';
                case 'S':
                case 'T':
                case 'U':
                    return '8';
                case 'V':
                case 'W':
                case 'X':
                case 'Y':
                case 'Z':
                    return '9';
                default: return val;
    
            }
        }
    }
    

    and here's how to do it without switch:

    public static char AlphaPhoneCharToNumber2(char val){
        // All three arrays are of exact same length
        var ualphas = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
        var lalphas = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
        var numval =  "22233344455566677788899999".ToCharArray();
        // thus I will loop up to the max length of one of the arrays
        // remember they are all the same length
        for(int i = 0; i < ualphas.Length; i++){
            //I will check if the value is in one of the alphabet
            //arrays at the current index
            //if there is a match I will assign it the number value
            //at the same index
            // MATCH UPPER?         MATCH LOWER?              RETURN NUMBER
            if(ualphas[i] == val || lalphas[i] == val) return numval[i];
        }
        // ELSE RETURN THE ORIGINAL VALUE
        return val;
    }
    
    0 讨论(0)
  • 2021-01-28 02:19

    While "map" (implemented as Dictionary in C#/.Net) is probably best choice for this problem, basic math is enough for such simple transformation:

     Console.WriteLine(String.Join("",  // combine characters back to string
           "555-GET-FOOD" //value
              .ToUpperInvariant() // carefully converting to avoid Turkish I problems
              .Select(c=> (c>='A' && c<='Z') ? // only tweak A-Z range
                 Math.Min((c-'A')/3+2,9).ToString()[0] : c)))
    
    0 讨论(0)
提交回复
热议问题