我有一个包含 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;
}
如果您已将数据读入有序集合,请说
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);