Created
October 31, 2023 04:40
-
-
Save Aragroth/e902977f82e783595cc25527a1070b31 to your computer and use it in GitHub Desktop.
Lab2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections; | |
| using System.Collections.ObjectModel; | |
| using System.Diagnostics; | |
| using System.Linq; | |
| using System.Reflection.Metadata; | |
| using System.Runtime.CompilerServices; | |
| using System.Runtime.Serialization; | |
| using System.Runtime.Serialization.Formatters.Binary; | |
| using System.Text.Json; | |
| using System.Text.Json.Serialization; | |
| using System.Xml; | |
| using System.Xml.Serialization; | |
| using static System.Runtime.InteropServices.JavaScript.JSType; | |
| public delegate void FValues(double x, ref double y1, ref double y2); | |
| public delegate DataItem FDI(double x); | |
| public struct DataItem | |
| { | |
| public double X { get; set; } | |
| public double Y1 { get; set; } | |
| public double Y2 { get; set; } | |
| public DataItem(double x, double y1, double y2) { X = x; Y1 = y1; Y2 = y2; } | |
| public string ToLongString(string format) | |
| { | |
| string formattedX = X.ToString(format); | |
| string formattedY1 = Y1.ToString(format); | |
| string formattedY2 = Y2.ToString(format); | |
| return $"X: {formattedX}, Y1: {formattedY1}, Y2: {formattedY2}"; | |
| } | |
| public override string ToString() | |
| { | |
| return this.ToLongString("F3"); | |
| } | |
| } | |
| public abstract class V1Data : IEnumerable<DataItem> | |
| { | |
| public string Key { get; set; } | |
| public DateTime Date { get; set; } | |
| public V1Data(string info, DateTime date) | |
| { | |
| Key = info; | |
| Date = date; | |
| } | |
| public abstract double MaxDistance { get; } | |
| public abstract string ToLongString(string format); | |
| public override string ToString() | |
| { | |
| return ToLongString("F3"); | |
| } | |
| public abstract IEnumerator<DataItem> GetEnumerator(); | |
| IEnumerator IEnumerable.GetEnumerator() | |
| { | |
| throw new NotImplementedException(); | |
| } | |
| } | |
| public class V1DataList : V1Data | |
| { | |
| public List<DataItem> Data { get; set; } | |
| public V1DataList(string key, DateTime date) : base(key, date) | |
| { | |
| Data = new List<DataItem>(); | |
| } | |
| public V1DataList(string key, DateTime date, double[] x, FDI F) : this(key, date) | |
| { | |
| HashSet<double> uniqueX = new HashSet<double>(); | |
| for (int i = 0; i < x.Length; i++) | |
| { | |
| double currentX = x[i]; | |
| if (!uniqueX.Contains(currentX)) | |
| { | |
| DataItem item = F(currentX); | |
| Data.Add(item); | |
| uniqueX.Add(currentX); | |
| } | |
| } | |
| } | |
| public override double MaxDistance | |
| { | |
| get | |
| { | |
| if (Data.Count < 2) return 0.0; | |
| double maxDist = double.MinValue; | |
| for (int i = 0; i < Data.Count - 1; i++) | |
| { | |
| for (int j = i + 1; j < Data.Count; j++) | |
| { | |
| double dist = Math.Abs(Data[i].X - Data[j].X); | |
| if (dist > maxDist) maxDist = dist; | |
| } | |
| } | |
| return maxDist; | |
| } | |
| } | |
| public static explicit operator V1DataArray(V1DataList source) | |
| { | |
| V1DataArray array = new V1DataArray(source.Key, source.Date, source.Data.Count); | |
| for (int i = 0; i < source.Data.Count; i++) | |
| { | |
| array.X[i] = source.Data[i].X; | |
| array.Y[0][i] = source.Data[i].Y1; | |
| array.Y[1][i] = source.Data[i].Y2; | |
| } | |
| return array; | |
| } | |
| public override string ToString() | |
| { | |
| return $"V1DataList: {Key}, Date: {Date} Count: {Data.Count}"; | |
| } | |
| public override string ToLongString(string format) | |
| { | |
| string dataItems = string.Join(Environment.NewLine, Data.Select( | |
| item => $"{item.ToLongString(format)}" | |
| )); | |
| return $"{ToString()}\n{dataItems}"; | |
| } | |
| public override IEnumerator<DataItem> GetEnumerator() | |
| { | |
| foreach (var item in Data) | |
| { | |
| yield return item; | |
| } | |
| } | |
| } | |
| public class V1DataArray : V1Data | |
| { | |
| public double[] X { get; set; } | |
| public double[][] Y { get; set; } | |
| public V1DataArray(string key, DateTime date, int N) : base(key, date) | |
| { | |
| X = new double[N]; | |
| Y = new double[2][]; | |
| Y[0] = new double[N]; | |
| Y[1] = new double[N]; | |
| } | |
| public V1DataArray(string key, DateTime date) : this(key, date, 0) { } | |
| public V1DataArray(string key, DateTime date, double[] x, FValues F) : base(key, date) | |
| { | |
| X = new double[x.Length]; | |
| Y = new double[2][]; | |
| Y[0] = new double[x.Length]; | |
| Y[1] = new double[x.Length]; | |
| X.CopyTo(x, 0); | |
| for (int i = 0; i < x.Length; i++) | |
| { | |
| F(x[i], ref Y[0][i], ref Y[1][i]); | |
| } | |
| } | |
| public V1DataArray(string key, DateTime date, int nX, double xL, double xR, FValues F) : this(key, date, nX) | |
| { | |
| double step = (xR - xL) / (nX - 1); | |
| for (int i = 0; i < nX; i++) | |
| { | |
| X[i] = xL + i * step; | |
| F(X[i], ref Y[0][i], ref Y[1][i]); | |
| } | |
| } | |
| public double[] this[int index] | |
| { | |
| get => Y[index]; | |
| } | |
| public V1DataList V1DataList | |
| { | |
| get | |
| { | |
| V1DataList list = new(base.Key, base.Date); | |
| for (int i = 0; i < X.Length; i++) | |
| { | |
| list.Data.Add(new DataItem(X[i], Y[0][i], Y[1][i])); | |
| } | |
| return list; | |
| } | |
| } | |
| public override double MaxDistance | |
| { | |
| get | |
| { | |
| if (X.Length < 2) return 0.0; | |
| double maxDist = double.MinValue; | |
| for (int i = 0; i < X.Length - 1; i++) | |
| { | |
| for (int j = i + 1; j < X.Length; j++) | |
| { | |
| double dist = Math.Abs(X[i] - X[j]); | |
| if (dist > maxDist) maxDist = dist; | |
| } | |
| } | |
| return maxDist; | |
| } | |
| } | |
| public override string ToString() | |
| { | |
| return $"V1DataArray: {Key}, Date: {Date} Count: {X.Length}"; | |
| } | |
| public override string ToLongString(string format) | |
| { | |
| string dataItems = ""; | |
| for (int i = 0; i < X.Length; i++) | |
| dataItems += $"X: {X[i].ToString(format)}, Y1: {Y[0][i].ToString(format)}, Y2: {Y[1][i].ToString(format)}\n"; | |
| return $"{ToString()}\n{dataItems}"; | |
| } | |
| public override IEnumerator<DataItem> GetEnumerator() | |
| { | |
| for (int i = 0; i < X.Length; i++) | |
| { | |
| yield return new DataItem(X[i], Y[0][i], Y[1][i]); | |
| } | |
| } | |
| public bool Save(string filename) | |
| { | |
| try | |
| { | |
| FileStream fout = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write); | |
| BinaryWriter bw = new BinaryWriter(fout); | |
| bw.Write(Key); | |
| bw.Write(Date.ToBinary()); | |
| bw.Write(X.Length); | |
| for (int i = 0; i < X.Length; i++) | |
| { | |
| bw.Write(X[i]); | |
| bw.Write(Y[0][i]); | |
| bw.Write(Y[1][i]); | |
| } | |
| fout.Close(); | |
| return true; | |
| } | |
| catch (Exception ex) | |
| { | |
| Console.WriteLine("Error while saving: " + ex.Message); | |
| return false; | |
| } | |
| } | |
| public static bool Load(string filename, ref V1DataArray dataArray) | |
| { | |
| try | |
| { | |
| FileStream fout = File.OpenRead(filename); | |
| BinaryReader bw = new BinaryReader(fout); | |
| dataArray.Key = bw.ReadString(); | |
| dataArray.Date = DateTime.FromBinary(bw.ReadInt64()); | |
| var length = bw.ReadInt32(); | |
| dataArray.X = new double[length]; | |
| dataArray.Y = new double[2][]; | |
| dataArray.Y[0] = new double[length]; | |
| dataArray.Y[1] = new double[length]; | |
| for (int i = 0; i < length; i++) | |
| { | |
| dataArray.X[i] = bw.ReadDouble(); | |
| dataArray.Y[0][i] = bw.ReadDouble(); | |
| dataArray.Y[1][i] = bw.ReadDouble(); | |
| } | |
| return true; | |
| } | |
| catch (Exception ex) | |
| { | |
| Console.WriteLine("Error while saving: " + ex.Message); | |
| return false; | |
| } | |
| } | |
| } | |
| public class V1MainCollection : ObservableCollection<V1Data> | |
| { | |
| public double norm(DataItem item) | |
| { | |
| return Math.Sqrt(Math.Pow(item.Y1, 2) + Math.Pow(item.Y2, 2)); | |
| } | |
| public double AverageValue | |
| { | |
| get | |
| { | |
| if (!this.Any()) return double.NaN; | |
| return this.SelectMany(item => item).Select(i => norm(i)).Average(); | |
| } | |
| } | |
| public DataItem? FarthestMeanItem | |
| { | |
| get | |
| { | |
| double avg = this.AverageValue; | |
| if (Double.IsNaN(avg)) return null; | |
| return this.SelectMany(item => item).OrderBy(item => Math.Abs(norm(item) - avg)).Last(); | |
| } | |
| } | |
| public IEnumerable<double>? NonUniqueMeasurmentsX | |
| { | |
| get | |
| { | |
| if (!this.Any()) return null; | |
| return this.Where(item => item is V1DataList).SelectMany(item => item).GroupBy(item => item.X).Where(group => group.Count() >= 2).Select(item => item.First().X); | |
| } | |
| } | |
| public V1MainCollection(int nV1DataArray, int nV1DataList) | |
| { | |
| for (int i = 0; i < nV1DataArray; i++) | |
| { | |
| V1DataArray dataArray = new( | |
| $"Array_Data{i}", DateTime.Now, 3, i, i + 6, | |
| delegate (double x, ref double y1, ref double y2) { y1 = 1; y2 = x * x; } | |
| ); | |
| this.Add(dataArray); | |
| } | |
| for (int i = 0; i < nV1DataList; i++) | |
| { | |
| V1DataArray dataArray = new( | |
| $"List_Data{i}", DateTime.Now, 3, i + 2, i + 6, | |
| delegate (double x, ref double y1, ref double y2) { y1 = x; y2 = x * x * x; } | |
| ); | |
| this.Add(dataArray.V1DataList); | |
| } | |
| } | |
| public bool Contains(string key) | |
| { | |
| foreach (var item in this) | |
| { | |
| if (item.Key == key) return true; | |
| } | |
| return false; | |
| } | |
| public new bool Add(V1Data v1Data) | |
| { | |
| if (!Contains(v1Data.Key)) | |
| { | |
| base.Add(v1Data); | |
| return true; | |
| } | |
| return false; | |
| } | |
| public string ToLongString(string format) | |
| { | |
| string result = ""; | |
| foreach (var item in this) | |
| { | |
| result += $"{item.ToLongString(format)}\n"; | |
| } | |
| return result; | |
| } | |
| public override string ToString() | |
| { | |
| string result = ""; | |
| foreach (var item in this) | |
| { | |
| result += item.ToString(); | |
| } | |
| return result; | |
| } | |
| } | |
| class Program | |
| { | |
| static void Main(string[] args) | |
| { | |
| LINQTester(); | |
| Console.ReadKey(); | |
| } | |
| static void firstLabTester() | |
| { | |
| Console.WriteLine("\n----- 1:"); | |
| V1DataList dataList = new("List_Data", DateTime.Now); | |
| dataList.Data.Add(new DataItem(1.0, 2.0, 3.0)); | |
| dataList.Data.Add(new DataItem(2.0, 3.0, 4.0)); | |
| Console.WriteLine(dataList.ToLongString("F3")); | |
| Console.WriteLine("\n----- 2:"); | |
| V1DataArray dataArray = (V1DataArray)dataList; | |
| Console.WriteLine(dataArray.ToLongString("F3")); | |
| Console.WriteLine("\n----- 3:"); | |
| V1DataArray dataArray2 = new( | |
| "Array_Data", DateTime.Now, 5, 10, 20, | |
| delegate (double x, ref double y1, ref double y2) { y1 = 1; y2 = x * x; } | |
| ); | |
| V1MainCollection mainCollection = new(3, 3); | |
| Console.WriteLine(mainCollection.ToLongString("F2")); | |
| Console.WriteLine("\n----- 4:"); | |
| foreach (V1Data data in mainCollection) | |
| { | |
| Console.WriteLine($"{data.Key} - Max Distance: {data.MaxDistance:F2}"); | |
| } | |
| } | |
| static void LINQTester() | |
| { | |
| V1MainCollection mainCollection = new(0, 0); | |
| V1MainCollection emptryMainCollection = new(0, 0); | |
| V1DataList dataList1 = new("List_Data1", DateTime.Now); | |
| dataList1.Data.Add(new DataItem(1.0, 3.0, 4.0)); | |
| dataList1.Data.Add(new DataItem(2.0, 3.0, 4.0)); | |
| dataList1.Data.Add(new DataItem(3.0, 3.0, 4.0)); | |
| V1DataList dataList2 = new("List_Data2", DateTime.Now); | |
| V1DataList dataList3 = new("List_Data3", DateTime.Now); | |
| dataList3.Data.Add(new DataItem(1.0, 3.0, 4.0)); | |
| dataList3.Data.Add(new DataItem(2.0, 6.0, 10.0)); | |
| V1DataArray dataArray1 = new("Array_Data1", DateTime.Now, 3); | |
| dataArray1.X = new double[] { -1.0, 3.0, 4.0 }; | |
| dataArray1.Y[0] = new double[] { 3.0, 3.0, 3.0 }; | |
| dataArray1.Y[1] = new double[] { 5.0, 5.0, 5.0 }; | |
| V1DataArray dataArray2 = new("Array_Data2", DateTime.Now, 0); | |
| mainCollection.Add(dataList1); | |
| mainCollection.Add(dataList2); | |
| mainCollection.Add(dataArray1); | |
| mainCollection.Add(dataList3); | |
| mainCollection.Add(dataArray2); | |
| Console.WriteLine("Тест на пустые данные:"); | |
| if (Double.IsNaN(emptryMainCollection.AverageValue)) | |
| { | |
| Console.WriteLine("AverageValue - NaN"); | |
| } | |
| if (emptryMainCollection.FarthestMeanItem == null) | |
| { | |
| Console.WriteLine("FarthestMeanItem - null"); | |
| } | |
| if (emptryMainCollection.NonUniqueMeasurmentsX == null) | |
| { | |
| Console.WriteLine("NonUniqueMeasurmentsX - null"); | |
| } | |
| Console.WriteLine($"\n{mainCollection.ToLongString("F2")}"); | |
| Console.WriteLine($"Среднее значение коллекции: {mainCollection.AverageValue}"); | |
| Console.WriteLine($"Наибольшое отклонение от среднего: {mainCollection.FarthestMeanItem}"); | |
| var arr = mainCollection.NonUniqueMeasurmentsX.ToArray(); | |
| Console.WriteLine("Точки встречающиеся несколько раз: "); | |
| foreach (var item in arr) | |
| { | |
| Console.WriteLine($"\tx - {item}"); | |
| } | |
| } | |
| static void TestLoadSaver() | |
| { | |
| Console.WriteLine("\n\n----- saving:"); | |
| V1DataArray dataArray2 = new( | |
| "Array_Data", DateTime.Now, 5, 10, 20, | |
| delegate (double x, ref double y1, ref double y2) { y1 = 1; y2 = x * x; } | |
| ); | |
| Console.WriteLine(dataArray2.ToLongString("F2")); | |
| dataArray2.Save("data.bin"); | |
| Console.WriteLine("\n\n----- loading:"); | |
| V1DataArray value = new("", DateTime.Now); | |
| V1DataArray.Load("data.bin", ref value); | |
| Console.WriteLine(value.ToLongString("F2")); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment