簡體   English   中英

從琴弦中提取溫度

[英]Extracting temperatures from a string

我目前正在嘗試從字符串中提取值。 所述字符串包含從CPU獲取的REAL溫度值:

IE(基於四核CPU)

    40.5 °C 42.4 °C 39.9 °C 40.0 °C 

(包含空格|根據核心數量,可能會有更少/更多的臨時)

我目前正在嘗試從單數字符串中獲取每個值,然后使用這些值查找平均值。 雖然我已經找到解決方法,但我的解決方案效率低下,包含多個循環等。

此功能用於查找CPU溫度的不斷更新的值(在實時更新的XAML上顯示),因此該算法需要盡可能高效。

如果您想尋求一種有效的算法,我將不勝感激!

這是正則表達式(縮寫為“ 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位數

第三行從輸入字符串中獲取所有匹配的子表達式。 其余代碼將結果吐入“調試”窗口以進行演示。

由於使用非常方便的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個核心-但只有少數具有更多核心),因此上述代碼的性能應該足夠。

正如Amy在評論中所說,使用Regex可以輕松解決此問題。
如果您想了解有關正則表達式的更多信息,建議您查看以下內容: https : //regexr.com/
如果您想測試自己的正則表達式,我建議您使用: https ://regex101.com

無論如何,要解決您的問題,我們將使用正則表達式以°C作為字面量來捕獲數字(40.5、42.4等)作為一個組: ([0-9]+(\\.[0-9][0-9]?)?) °C試試看 )。

[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);
}

這是正則表達式解決方案:

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();
        }
    }
}

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個字符以查找下一個溫度。

這樣的算法非常快,因為它完成該工作所需的工作量最少。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM