如何获取数组中最接近的值并插入实数

问题描述 投票:0回答:1

我有一个包含 10.000 行的文本文件,内容如下:

16500000000 -11.6560625775

16600000000 -11.99428283515

16700000000 -12.06410749998

16800000000 -11.81220239236

我想在 C# 中创建一个函数,在其中传递文件名和第一列的数字。然后输出是第二列的值。 如果在第 1 列中找不到该数字,则应插入该值。

意味着,当我输入 16600000000 时,函数返回 -11.99428283515。

当我输入 16650000000 时,函数应该在 166.. 和 167...之间插入值

目前我有这个代码,但没有插值。

如何通过插值(并且快速)更好地完成此操作:

public static int GetPw(string filePath, double Freq, out double power, out string errMsg)
    {
        power = Double.MinValue;
        errMsg = "No error";
        try
        {


            string[] lines = File.ReadAllLines(filePath);
            var filteredLines = lines.Where(line => !line.Contains("#") && !line.Contains("!") && !line.Contains("IND"));
            var splitLines = filteredLines.Select(line => line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
            var validLines = splitLines.Where(parts => parts.Length >= 2);
            var sortedLines = validLines.OrderBy(parts => Math.Abs(float.Parse(parts[0]) - targetFrequency));
            string closestPower = sortedLines.Select(parts => parts[1]).FirstOrDefault();


            if (!Double.TryParse(closestPower, CultureInfo.InvariantCulture, out power))
            {
                power = Double.MinValue;
                throw new InvalidCastException($"{power} is not a valid power value");
            }
        }
        catch (Exception e)
        {
            errMsg=e.Message;
            return -1;
        }
        return 0;
    }
c# interpolation frequency
1个回答
0
投票

如果您已将数据读入有序集合,请说

List<(double x, double y)>

var data = new List<(double x, double y)> {
  (1, 123),
  (2, 234),
  (3, 345),
};

你可以尝试二分搜索,即

private static double Interpolate(List<(double x, double y)> list, double x) {
  if (list.Count == 0)
    return double.NaN;

  if (list.Count == 1)
    return list[0].y;

  var index = list.BinarySearch((x, 0),
    Comparer<(double x, double y)>.Create((left, right) => left.x.CompareTo(right.x)));

  if (index >= 0)
    return list[index].y;

  int leftIndex = ~index - 1;

  if (leftIndex < 0)
    leftIndex = 0;

  int rightIndex = leftIndex + 1;

  if (rightIndex == list.Count) {
    leftIndex -= 1;
    rightIndex -= 1;
  }

  double xa = list[leftIndex].x;
  double ya = list[leftIndex].y;

  double xb = list[rightIndex].x;
  double yb = list[rightIndex].y;

  return ya + (x - xa) / (xb - xa) * (yb - ya);
}

我们来看看:

var y = Interpolate(data, 1.5);

// 178.5
Console.WriteLine(y);

小提琴https://dotnetfiddle.net/zEDD5g

© www.soinside.com 2019 - 2024. All rights reserved.