我目前正在尝试从字符串中提取值。所述字符串包含从CPU获取的REAL温度值:
I.E。 (基于四核CPU)
40.5 °C 42.4 °C 39.9 °C 40.0 °C
(包含空格|取决于核心数,可能会有更少/更多的临时文件)
我目前正在尝试从单数字符串中获取每个值,然后使用这些值查找平均值。虽然我已经找到解决方法,但我的解决方案效率低下,包含多个循环等。
此函数用于查找实时更新的XAML上显示的CPU温度的不断更新的值,因此算法需要尽可能高效。
如果您想寻求一种高效的算法,我将不胜感激!
答案 0 :(得分:4)
这是正则表达式(缩写为“ regex”)的理想选择。
var input = "40.5 °C 42.4 °C 39.9 °C 40.0 °C ";
var regex = new Regex(@"\d{1,2}\.\d");
var matches = regex.Matches(input);
foreach (Match m in matches)
{
Debug.WriteLine(m.Value);
}
好的,这是做什么的?
var regex = new Regex(@"\d{1,2}\.\d");
这将设置具有特定格式的新正则表达式。在这种情况下,我们要匹配:
\d{1,2}
:{1,2}
表示将前面的令牌匹配1-2次。我假设您的温度范围是0.0到99.0。如果超出此范围,则需要修改此行。您可以将范围更改为\d{1,3}
以允许第三个数字,或者将\d+
允许一个或多个连续数字。\.
:一个句点-必须省略句点,因为句点在正则表达式中具有特殊含义\d
:1位数字第三行从输入字符串中获取所有匹配的子表达式。其余代码会将结果吐入“调试”窗口以进行演示。
答案 1 :(得分:4)
由于使用非常方便的System.String.Split()
函数没有答案,因此-这里是一个:
double[] Parse(string s)
{
var valueStrings = s.Split(new string[] { " ", "°C" },
System.StringSplitOptions.RemoveEmptyEntries);
return valueStrings.Select(xs => System.Double.Parse(xs)).ToArray();
}
理论上,手工编织的实现可能会更快,因为从技术上讲,此解决方案在字符串上进行迭代,然后在拆分结果上进行迭代。仅需一次迭代即可完成这两个步骤。但是由于您拥有的内核数量将受到限制(我有6个内核,有些具有32或64个内核-但只有少数具有更多内核),因此上述代码的性能应该足够。
答案 2 :(得分:1)
正如Amy在评论中所说,使用Regex可以轻松解决此问题。
如果您想了解有关正则表达式的更多信息,建议您查看以下内容:https://regexr.com/
如果您想测试自己的正则表达式,建议您使用:https://regex101.com
无论如何,要解决您的问题,我们将使用正则表达式以°C为常量来捕获数字(40.5、42.4等)为一组:
([0-9]+(\.[0-9][0-9]?)?) °C
(try it)。
[0-9]+(\.[0-9][0-9]?)?
捕获几乎所有可能的十进制数字,因此它应该涵盖所有可能的温度。
这将为您提供一组号码,然后您可以根据需要使用该号码。在C#环境中:
string str = "40.5 °C 42.4 °C 39.9 °C 40.0 °C ";
foreach (Match match in Regex.Matches(str, @"([0-9]+(\.[0-9][0-9]?)?) °C"))
{
Console.WriteLine(match.Groups[1].Value);
}
答案 3 :(得分:1)
这是正则表达式解决方案:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleApplication55
{
class Program
{
static void Main(string[] args)
{
string input = "40.5 °C 42.4 °C 39.9 °C 40.0 °C";
string pattern = "(?'temp'[^ ]+) °C";
decimal[] temperatures = Regex.Matches(input, pattern).Cast<Match>().Select(x => decimal.Parse(x.Groups["temp"].Value)).ToArray();
}
}
}
答案 4 :(得分:-4)
OP明确了他的要求,以允许单位温度。给你。
string temps = "1.1 °C 40.5 °C 42.4 °C 39.9 °C 40.0 °C 4.0 °C 11.1 °C";
decimal sum = 0m;
int count = 0;
for (int i = 0; i < temps.Length; i += temps[i + 4] == ' ' ? 8 : 7)
{
string t = temps.Substring(i, 4).TrimEnd();
Console.WriteLine(t);
sum += Decimal.Parse(t);
count++;
}
decimal avg = sum / count;
Console.WriteLine("Avg = " + avg.ToString());
这应该比基于正则表达式的解决方案高效得多。
通过从字符串中获取4个字符,将其转换为小数,然后将其添加到总和中来工作。然后,根据第四个字符是否为空格,它会向前跳7个或8个字符以查找下一个温度。
这样的算法非常快,因为它完成该工作所需的工作量最少。