线性差值法结构类(面向对象的方式)

Posted kexb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性差值法结构类(面向对象的方式)相关的知识,希望对你有一定的参考价值。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication7
{
    public enum PointState
    {
        Inner = 0,//定义域的点
        Mid = 1,//未超出定义域的点
        LeftOuter = 2,//超出左侧
        RightOuter = 3//超出右侧
    }
    public class Point
    {
        public Point Left;
        public Point Right;
        public double x { get; set; }
        public double y { get; set; }

        public PointState state { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            double[] xarr = new double[] { 7 }; //{ 7, 9, 5, 13, 11 ,14,  15, 16,17,18,19,20,21,22,23,24,25,26,27,28};

            double[] yarr = new double[] { 4 }; //{ 4, 9, 10, 12, 15, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 };
            //求解的点
            double[] x1arr = new double[] { 1, 2, 3, 4, 6, 8, 11, 13, 14, 16, 17 };
            double[] y1arr;
            var pointDictionary = LineDifferenceMethod(xarr, yarr, x1arr, out y1arr, true);
            Console.Read();
        }
        /// <summary>
        /// 线性差值法
        /// </summary>
        /// <param name="xarr">原始数据x轴</param>
        /// <param name="yarr">原始数据y轴</param>
        /// <param name="x1arr">求解的x轴的点的数组</param>
        /// <param name="extension">边缘点是否使用斜率延伸</param>
        /// <returns></returns>
        public static Dictionary<double, Point> LineDifferenceMethod(double[] xarr, double[] yarr, double[] x1arr, out double[] y1arr, bool extension = false)
        {
            List<Point> points = new List<Point>();
            List<double> xarrcopy = xarr.OrderBy(x => x).ToList();
            for (int i = 0; i < xarr.Length; i++)
            {
                Point p = new Point();
                p.x = xarr[i];
                p.y = yarr[i];
                p.state = PointState.Inner;
                points.Add(p);
            }
            if (points.Count == 1)
            {
                for (int i = 0; i < x1arr.Length; i++)
                {
                    Point p = new Point();
                    p.x = x1arr[i];
                    p.y = yarr[0];
                    if (p.x != xarr[0])
                    {
                        if (p.x < xarr[0])
                        {
                            p.state = PointState.LeftOuter;
                        }
                        else if (p.x > xarr[0])
                        {
                            p.state = PointState.RightOuter;
                        }
                        points.Add(p);
                    }

                }
                y1arr = points.ToDictionary(p => p.x).Select(p => p.Value.y).ToArray();
                return points.ToDictionary(p => p.x);
            }

            Point firstPoint = points.OrderBy(p => p.x).ToArray().FirstOrDefault();
            Point lastPoint = points.OrderBy(p => p.x).ToArray().LastOrDefault();
            Dictionary<double, Point> pointDict = points.ToDictionary(p => p.x);
            for (int i = 0; i < x1arr.Length; i++)
            {
                Point p = new Point();
                double qx = x1arr[i];
                p.x = qx;
                p.y = 0;
                if (qx < xarrcopy[0])
                {
                    p.state = PointState.LeftOuter;

                }
                else if (qx > xarrcopy[xarrcopy.Count - 1])
                {
                    p.state = PointState.RightOuter;
                }
                else if (pointDict.ContainsKey(qx))
                {
                    //内部点不用求了
                    p = pointDict[qx];
                    continue;
                }
                else
                {
                    p.state = PointState.Mid;
                }
                points.Add(p);

            }
            points = points.OrderBy(p => p.x).ToList();

            for (int i = 0; i < points.Count; i++)
            {

                Point p = points[i];
                if (i == 0)
                {
                    p.Left = null;
                    if (points.Count > 1)
                    {
                        p.Right = points[i + 1];
                    }
                    else
                    {
                        p.Right = null;
                    }

                }
                else if (i == points.Count - 1)
                {
                    p.Right = null;
                    if (points.Count > 1)
                    {
                        p.Left = points[i - 1];
                    }
                    else
                    {
                        p.Right = null;
                    }
                }
                else if (i > 0 && i < points.Count - 1)
                {
                    p.Left = points[i - 1];
                    p.Right = points[i + 1];
                }

            }
            foreach (var item in points)
            {
                if (item.state == PointState.Mid)
                {
                    var right = item.Right;
                    var left = item.Left;
                    AdjustLeftRight(ref right, ref left, item);

                }
                else if (item.state == PointState.LeftOuter)
                {

                    if (!extension)
                    {
                        item.y = firstPoint.y;
                    }
                    else
                    {
                        var right = firstPoint.Right;
                        var left = firstPoint;
                        AdjustLeftRight(ref right, ref left, item);



                    }
                }
                else if (item.state == PointState.RightOuter)
                {
                    if (!extension)
                    {
                        item.y = lastPoint.y;
                    }
                    else
                    {
                        var right = lastPoint;
                        var left = lastPoint.Left;
                        AdjustLeftRight(ref right, ref left, item);


                    }
                }
            }
            pointDict = points.ToDictionary(p => p.x);
            y1arr = pointDict.Where(p => x1arr.Contains(p.Key)).Select(x => x.Value.y).ToArray();
            return pointDict;

        }

        private static void AdjustLeftRight(ref Point right, ref Point left, Point item)
        {
            while (right.state != PointState.Inner)
            {
                right = right.Right;
            }
            while (left.state != PointState.Inner)
            {
                left = left.Left;
            }
            double k = (right.y - left.y) / (right.x - left.x);//斜率
            item.y = left.y + k * (item.x - left.x);
        }
    }
}

 

以上是关于线性差值法结构类(面向对象的方式)的主要内容,如果未能解决你的问题,请参考以下文章

杨玲 徐思 《面向对象程序设计(java)》第十一周学习总结

线性表——顺序存储结构之静态链表

第八周

扎实打牢数据结构算法根基,从此不怕算法面试系列之005 week01 02-05 使用自定义类测试我们前面实现的支持泛型的线性查找法

如何通过单击片段内的线性布局从片段类开始新活动?下面是我的代码,但这不起作用

Python 七Python类与面向对象