Разработать класс ДлинноеЧисло, перегрузив определенные операции - C#

Узнай цену своей работы

Формулировка задачи:

Ребята, правда, поймите и помилуйте! У меня уже идет сессия и по сишарпу осталось сдать последную прогу на длинную арфиметику. Ничего не успеваю и плохо понимаю сишарп Сделайте , пожалуйста. Хорошо понимаю с++, но синтаксис C# просто убивает! Разработать класс ДлинноеЧисло, перегрузив следующие операции(если они у вас есть): a) присваивание; b) умножение; c) сложение; d) вычитание; e) деление; f) остаток от деления; g) операции отношения (сравнения); решить задачу с целыми неотрицательными длинными числами. В основной программе создать массив длинных чисел и выполнить его сортировку по возрастанию. Найти количество делителей n-значного натурального числа (n > 20).

Решение задачи: «Разработать класс ДлинноеЧисло, перегрузив определенные операции»

textual
Листинг программы
    public class LongNumber : IComparable<LongNumber>
    {
        /// <summary>
        /// Основание системы счисления
        /// </summary>
        public const byte BASE = 10;
 
        /// <summary>
        /// Цифры числа, начиная с младшего разряда
        /// </summary>
        List<byte> digits = new List<byte>();
 
        #region Public methods
 
        /// <summary>
        /// Удаляет незначащие нули
        /// </summary>
        public void Normalize()
        {
            while(digits.Count > 0 && digits[digits.Count - 1] == 0)
                digits.RemoveAt(digits.Count -1);
        }
 
        /// <summary>
        /// Клон
        /// </summary>
        /// <returns></returns>
        public LongNumber Clone()
        {
            return new LongNumber {digits = new List<byte>(digits)};
        }
 
        /// <summary>
        /// Сдвиг
        /// </summary>
        public void Shift(int shift)
        {
            if (shift > 0)
                digits.InsertRange(0, Enumerable.Repeat<byte>(0, shift));
            if (shift < 0)
                if (-shift >= digits.Count)
                    digits.Clear();
                else
                    digits.RemoveRange(0, -shift);
        }
 
        #endregion
 
        #region Operations
 
        public static LongNumber Add(LongNumber n1, LongNumber n2)
        {
            var res = new LongNumber();
            var count = Math.Max(n1.digits.Count, n2.digits.Count);
            var carry = 0;
            for (var i = 0; i < count; i++)
            {
                var sum = n1[i] + n2[i] + carry;
                carry = sum / BASE;
                sum %= BASE;
                res.Add(sum);
            }
 
            if (carry > 0)
                res.Add(carry);
 
            return res;
        }
 
        public static LongNumber Sub(LongNumber n1, LongNumber n2)
        {
            var res = new LongNumber();
            var count = Math.Max(n1.digits.Count, n2.digits.Count);
            var carry = 0;
 
            for (var i = 0; i < count; i++)
            {
                var diff = n1[i] - n2[i] - carry;
                carry = 0;
                while (diff < 0)
                {
                    diff += BASE;
                    carry++;
                }
                res.Add(diff);
            }
 
            if (carry > 0) throw new Exception("Negative result");
            res.Normalize();
 
            return res;
        }
 
        private static LongNumber Mul(LongNumber n, int digit)
        {
            var res = new LongNumber();
            var count = n.digits.Count;
            var carry = 0;
            for (var i = 0; i < count; i++)
            {
                var sum = n[i] * digit + carry;
                carry = sum / BASE;
                sum %= BASE;
                res.Add(sum);
            }
 
            if (carry > 0)
                res.Add(carry);
 
            res.Normalize();
 
            return res;
        }
 
        
        public static LongNumber Mul(LongNumber n1, LongNumber n2)
        {
            var res = new LongNumber();
            var n = n1.Clone();
 
            for(int i=0;i<n2.digits.Count;i++)
            {
                var digit = n2[i];
                res = res + Mul(n, digit);
                n.Shift(1);
            }
 
            return res;
        }
 
        public static void Div(LongNumber n1, LongNumber n2, out LongNumber div, out LongNumber rest)
        {
            if (n2.digits.Count == 0)
                throw new Exception("Zero divide");
 
            //только остаток
            if(n1 < n2)
            {
                div = new LongNumber();
                rest = n1.Clone();
                return;
            }
 
            //выравниваем число знаков
            var n = n2.Clone();
            var shift = n1.digits.Count - n.digits.Count;
            n.Shift(shift);
 
            if (n1 < n)
            {
                n.Shift(-1);
                shift--;
            }
 
            //подбираем множитель
            var res = n.Clone();
            var m = 1;
            while (res <= n1)
            {
                m++;
                res = Mul(n, m);
            }
            m--;
 
            //остаток
            rest = n1 - Mul(n, m);
 
            //формируем частное
            div = new LongNumber();
            div.Add(m);
            div.Shift(shift);
 
            //продолжаем деление
            if (rest >= n2)
            {
                LongNumber temp;
                Div(rest, n2, out temp, out rest);
                div = Add(div, temp);
            }
 
            //
            div.Normalize();
            rest.Normalize();
        }
 
        #endregion
 
        #region Routines
 
        int this[int i]
        {
            get { return i >= digits.Count ? 0 : digits[i]; }
        }
 
        void Add(int digit)
        {
            digits.Add((byte)digit);
        }
 
        #endregion
 
        #region Operators
 
        public static LongNumber operator +(LongNumber n1, LongNumber n2)
        {
            return Add(n1, n2);
        }
 
        public static LongNumber operator -(LongNumber n1, LongNumber n2)
        {
            return Sub(n1, n2);
        }
 
        public static LongNumber operator *(LongNumber n1, LongNumber n2)
        {
            return Mul(n1, n2);
        }
 
        public static LongNumber operator /(LongNumber n1, LongNumber n2)
        {
            LongNumber div, rest;
            Div(n1, n2, out div, out rest);
            return div;
        }
 
        public static LongNumber operator %(LongNumber n1, LongNumber n2)
        {
            LongNumber div, rest;
            Div(n1, n2, out div, out rest);
            return rest;
        }
 
        public static bool operator >(LongNumber n1, LongNumber n2)
        {
            return n1.CompareTo(n2) > 0;
        }
 
        public static bool operator <(LongNumber n1, LongNumber n2)
        {
            return n1.CompareTo(n2) < 0;
        }
 
        public static bool operator >=(LongNumber n1, LongNumber n2)
        {
            return n1.CompareTo(n2) >= 0;
        }
 
        public static bool operator <=(LongNumber n1, LongNumber n2)
        {
            return n1.CompareTo(n2) <= 0;
        }
 
        public static bool operator ==(LongNumber n1, LongNumber n2)
        {
            return n1.CompareTo(n2) == 0;
        }
 
        public static bool operator !=(LongNumber n1, LongNumber n2)
        {
            return n1.CompareTo(n2) != 0;
        }
 
        #endregion
 
        #region Conversions
 
        public static explicit operator String(LongNumber num)
        {
            return num.ToString();
        }
 
        public static implicit operator LongNumber(string str)
        {
            return LongNumber.Parse(str);
        }
 
        public static LongNumber Parse(string str)
        {
            var res = new LongNumber();
            foreach (var c in str.Reverse())
                res.digits.Add(Convert.ToByte(c.ToString(), BASE));
            res.Normalize();
            return res;
        }
 
        #endregion
 
        #region IComparable
 
        public int CompareTo(LongNumber other)
        {
            var res = digits.Count.CompareTo(other.digits.Count);
            if(res == 0)
            {
                if (digits.Count == 0) return 0;
                for (int i = digits.Count - 1; i >= 0 && res == 0; i--)
                    res = digits[i].CompareTo(other.digits[i]);
            }
 
            return res;
        }
 
        #endregion
 
        #region Overrided methods
 
        public override bool Equals(object obj)
        {
            var other = obj as LongNumber;
            if (other == null)
                return false;
 
            return this == other;
        }
 
        public override int GetHashCode()
        {
            return digits.Sum(b => b);
        }
 
        public override string ToString()
        {
            if (digits.Count == 0)
                return "0";
 
            return string.Join("", digits.Reverse<byte>().Select(b => Convert.ToString(b, BASE)));
        }
 
        #endregion
    }

Оцени полезность:

12   голосов , оценка 3.917 из 5
Похожие ответы