Implementacion de suma de cadenas parte II

Como mejora de la implementacion anterior y estudio de C#, sobretodo en las mejoras incoorporadas en la version 4, me decidi a implementar una nueva version de esta suma. Basicamente los cambios agregados fue la suma por bloques y la suma de ceros, que pienso yo que reduce la cantidad de operaciones, por lo menos unas 19 veces ya que es el bloque de numeros que toma.

Habria que hacer un profundo analisis en revisar la cantidad de codigo usado si este mejora el performance del algoritmo.

StringInteger.cs

...
        public static readonly int MAX_ULONG_LENGTH = ulong.MaxValue.ToString().Length;
...
        public static StringInteger operator +(StringInteger lhs, StringInteger rhs)
        {
            //Validaciones

            String tmpX = lhs.Container, tmpY = rhs.Container;
            ulong x, y, result = 0;
            int limit = lhs.Container.Length > rhs.Container.Length ? lhs.Container.Length : rhs.Container.Length;
            StringBuilder tmp = new StringBuilder(limit);
            do
            {
                if (IsTheOnlyOperand(ref tmpX, ref tmpY, (int)result))
                {
                    result = 0;
                    tmp.Insert(0, tmpX + tmpY);
                }
                else
                {
                    x = RetrieveNextNumber(ref tmpX);
                    y = RetrieveNextNumber(ref tmpY);

                    result += x + y;
                    if (result.ToString().Length == MAX_ULONG_LENGTH)
                    {
                        tmp.Insert(0, result.ToString().Substring(1));
                        result = 1;
                    }
                    else
                    {
                        tmp.Insert(0, result);
                        result = 0;
                    }
                }
            } while (!(string.IsNullOrEmpty(tmpX) && string.IsNullOrEmpty(tmpY)));
            tmp.Insert(0, result);

            return new StringInteger(tmp.ToString());
        }//operator+

        private static bool IsTheOnlyOperand(ref string firstOperand, ref string secondOperand, int carry)
        {
            bool response = false;
            firstOperand = SanitizeStringInput(firstOperand);
            secondOperand = SanitizeStringInput(secondOperand);

            if (string.IsNullOrEmpty(firstOperand) && !string.IsNullOrEmpty(secondOperand))
            {

                secondOperand = secondOperand.Substring(0, secondOperand.Length - 1) +
                    Convert.ToChar(Convert.ToInt32(secondOperand[secondOperand.Length - 1]) + carry);
                response = true;
            }
            else if (string.IsNullOrEmpty(secondOperand) && !string.IsNullOrEmpty(firstOperand))
            {
                firstOperand = firstOperand.Substring(0, firstOperand.Length - 1) +
                    Convert.ToChar(Convert.ToInt32(firstOperand[firstOperand.Length - 1]) + carry);
                response = true;
            }

            return response;
        }//IsTheOnlyOperand

        private static string SanitizeStringInput(string input)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }

            input = input.TrimStart('0').Trim();
            if ("".Equals(input))
            {
                input = "0";
            }

            Regex pattern = new Regex(@"^d+$");
            if (!pattern.IsMatch(input))
            {
                throw new ArgumentException("The string value " + input + " is not a integer value");
            }

            return input;
        }//SanitizeStringInput

        private static ulong RetrieveNextNumber(ref string stringNumber)
        {
            int length = stringNumber.Length > MAX_ULONG_LENGTH - 1 ? MAX_ULONG_LENGTH - 1 : stringNumber.Length;
            int index = stringNumber.Length - length;
            ulong number = length > 0 ? ulong.Parse(stringNumber.Substring(index, length)) : 0;
            stringNumber = stringNumber.Remove(index, length);

            return number;
        }//RetrieveNextNumber

Leave a Reply