Example #1
0
        public IEnumerator <T> GetEnumerator()
        {
            IValuesAndLink <T> value = _count > 0 ? _arr[_firstIndex] : null;

            while (value != null)
            {
                yield return(value.Value);

                value = value.Next;
            }
            ;
        }
Example #2
0
        public bool Remove(IValuesAndLink <T> elementNode)
        {
            var flag     = false;
            var variable = _arr[_firstIndex];

            while (variable._enable)
            {
                if (variable.Equals(elementNode))
                {
                    Removing(variable._index);
                    flag = true;
                    break;
                }
                variable = variable.Next;
            }
            return(flag);
        }
Example #3
0
        //далее исполнены все стандартные методы, необходимые для выполнения идеологии листа

        public void AddAfter(IValuesAndLink <T> elementNode, T elenet)
        {
            Count++;
            var newIndex = _arr[_lastIndex]._nextIndex;
            var node     = (ValuesAndLink)elementNode;

            Removing(_arr[_lastIndex]._nextIndex);
            if (node._index == _lastIndex)
            {
                _lastIndex = newIndex;
            }

            Count++;
            _arr[newIndex].Value          = elenet;
            _arr[newIndex]._enable        = true;
            _arr[newIndex]._nextIndex     = node._nextIndex;
            node._nextIndex               = newIndex;
            _arr[newIndex]._previousIndex = node._index;
        }
Example #4
0
        //тут определяем знак и его приоритет
        private char FindOperand(ref IValuesAndLink <char> charter, out int intPreor)
        {
            if (charter == null)
            {
                intPreor = 0;
                return(default(char));
            }
            switch (charter.Value)
            {
            case '+':
            case '-':
                charter  = charter.Next ?? throw new Exception("Отсутствует слагаемое в конце");
                intPreor = 0;
                return(charter.Previous.Value);

            case '*':
            case '/':

                charter  = charter.Next ?? throw new Exception("Отсутствует множитель в конце");
                intPreor = 1;
                return(charter.Previous.Value);

            case '^':
                charter  = charter.Next ?? throw new Exception("Отсутствует показатель в конце");
                intPreor = 2;
                return(charter.Previous.Value);

            case ')':
                if (_braketsNumber == 0)
                {
                    throw new Exception("Лишня скобка");
                }
                _braketsNumber--;
                var temp = charter.Value;
                charter  = charter.Next;
                intPreor = -1;
                return(temp);

            default:
                intPreor = 1;
                return('*');
            }
        }
Example #5
0
        //определение функции
        private void FindFunc(ref IValuesAndLink <char> nodeValue, out FuncEnum funcValue)
        {
            funcValue = FuncEnum.Nun;
            var strFunc = "";

            while (nodeValue != null && !NumbersPredicate(nodeValue.Value) && nodeValue.Value != UnoMinus && nodeValue.Value != OpenBracket && nodeValue.Value != CharVariable)
            {
                strFunc  += nodeValue.Value;
                nodeValue = nodeValue.Next;
            }

            switch (strFunc)
            {
            case "sin":
            {
                funcValue = FuncEnum.Sin;
                break;
            }

            case "cos":
            {
                funcValue = FuncEnum.Cos;
                break;
            }

            case "log":
            {
                funcValue = FuncEnum.Log;
                break;
            }

            default:
            {
                if (strFunc.Length > 0)
                {
                    throw new Exception("Введён неверный оператор");
                }
                break;
            }
            }
        }
Example #6
0
        //определение значения, вычисление унарных минусов как перед, так и внутри функции, всё здесь
        private IOperand FindValue(ref IValuesAndLink <char> charter)
        {
            if (charter == null)
            {
                return(null);
            }
            //if(charter == null) throw new Exception("Закрывайте скобки");
            var      blUno1 = false;
            var      blUno2 = false;
            IOperand aValue;
            var      strNumbs = "";

            //унарный минус перед функцией
            if (charter.Value == UnoMinus)
            {
                blUno1  = true;
                charter = charter.Next;
            }
            //определяем наличие функции
            FindFunc(ref charter, out FuncEnum funcValue);
            if (charter.Value == OpenBracket)
            {
                //рекурсия для скобок
                charter = charter.Next;
                _braketsNumber++;
                aValue = StrResult(false, ref charter, out char tempOper, out int tempPreor);
            }
            else
            {
                //унарный минус внутри функции
                if (charter.Value == UnoMinus)
                {
                    blUno2  = true;
                    charter = charter.Next;
                }
                //само число
                while (charter != null && NumbersPredicate(charter.Value))
                {
                    strNumbs += charter.Value;
                    charter   = charter.Next;
                }
                //x с числом
                if (charter?.Value == CharVariable)
                {
                    aValue  = strNumbs == "" ? (IOperand) new Variable() : new Umn(new Const(Double.Parse(strNumbs.Replace('.', ','))), new Variable());
                    charter = charter.Next;
                }
                //x без числа
                else
                {
                    if (strNumbs == "")
                    {
                        throw new Exception("не указан аргумент функции");
                    }
                    aValue = new Const(strNumbs == "" ? 1 : Double.Parse(strNumbs.Replace('.', ',')));
                }
                //вычисление внутреннего унарного минуса
                if (blUno2)
                {
                    aValue = UnoOperand(aValue, FuncEnum.Min);
                }
            }
            //подсчёт функции
            aValue = UnoOperand(aValue, funcValue);
            //подсчёт унарного минуса перед функцией
            if (blUno1)
            {
                aValue = UnoOperand(aValue, FuncEnum.Min);
            }
            return(aValue);
        }
Example #7
0
        /// <summary>
        /// вычисляет результат операций внутри скобки
        /// </summary>
        /// <param name="preOperand">наличие знака перед последовательностью опарандов высшего порядка</param>
        /// <param name="sValue">каретка</param>
        /// <param name="lastOperand">тип операнда после скобки</param>
        /// <param name="lastOperandPreor">и его преоритет</param>
        /// <returns></returns>
        private IOperand StrResult(bool preOperand, ref IValuesAndLink <char> sValue, out char lastOperand, out int lastOperandPreor)
        {
            if (sValue == null)
            {
                lastOperand      = default(char);
                lastOperandPreor = -1;
                return(null);
            }
            //определяем первое число. Тут же вычисляются все унарные опреаторы.
            var a = FindValue(ref sValue);
            //знак
            var operand = FindOperand(ref sValue, out int operandPreor);

            //если скобка закрывается или последовательность операндов высшего приоритета завершена, то возвращаемся по дереву
            if (operand == CloseBracket || preOperand && operandPreor < 2)
            {
                lastOperand      = operand;
                lastOperandPreor = operandPreor;
                return(a);
            }

            do
            {
                //сложение вычисляем в самом конце.
                if (operandPreor == 0)
                {
                    var m = StrResult(true, ref sValue, out lastOperand, out lastOperandPreor);
                    if (m == null && operand == default(char))
                    {
                        return(a);
                    }
                    var p = DuoOperand(a, m, operand);
                    return(p);
                }

                var b           = FindValue(ref sValue);
                var nextOperand = FindOperand(ref sValue, out int nextOperandPreor);

                //сравниваем приоритеты
                if (operandPreor >= nextOperandPreor)
                {
                    if (b == null && operand == default(char))
                    {
                        break;
                    }
                    a            = DuoOperand(a, b, operand);
                    operand      = nextOperand;
                    operandPreor = nextOperandPreor;
                }
                else
                {
                    //если приоритет меньше, то перед нами последовательность операндов высшего приоритетов (возведение в степень)
                    a = DuoOperand(a,
                                   DuoOperand(b, StrResult(true, ref sValue, out char tempOperand, out operandPreor),
                                              nextOperand), operand);
                    operand = tempOperand;
                }
            } while (operand != CloseBracket && sValue != null);
            lastOperand      = default(char);
            lastOperandPreor = -1;
            return(a);
        }