我必须替换一个字符串中的多个子字符串(输入字符串的最大长度32)。我有一本大字典,其中有成千上万的项作为键值对。我需要检查每个词是否在字典中存在,如果在字典中存在,则用相应的值替换。输入的字符串可以有多个尾随空格。
此方法被称为数百万次,因此,它严重影响了性能。
代码中是否存在任何优化范围或其他更好的方法来实现此目的。
public static string RandomValueCompositeField(object objInput, Dictionary<string, string> g_rawValueRandomValueMapping) {
if (objInput == null)
return null;
string input = objInput.ToString();
if (input == "")
return input;
//List<string> ls = new List<string>();
int count = WhiteSpaceAtEnd(input);
foreach (string data in input.Substring(0, input.Length - count).Split(' ')) {
try {
string value;
gs_dictRawValueRandomValueMapping.TryGetValue(data, out value);
if (value != null) {
//ls.Add(value.TrimEnd());
input = input.Replace(data, value);
}
else {
//ls.Add(data);
}
}
catch(Exception ex) {
}
}
//if (count > 0)
// input = input + new string(' ', count);
//ls.Add(new string(' ', count));
return input;
}
编辑:
我错过了问题中的一件重要事情。子字符串只能在输入字符串中出现一次。 Dictionay键和值的字符数相同。
答案 0 :(得分:0)
这是一种方法,该方法将采用输入字符串,并通过查找“单词”(任何连续的非空白),然后检查该单词是否在字典中并将其替换为相应的值(如果找到)来构建新的字符串。这将解决Replace
替换“子词”的问题(如果您拥有“ hello hell”,并且想要将“ hell”替换为“ heaven”,而又不希望它给您“天国天堂”)。它还解决了交换问题。例如,如果要在“是”中将“是”替换为“否”,将“否”替换为“是”,则不希望它先将其转换为“否”,然后再转换为“是”。
public string ReplaceWords(string input, Dictionary<string, string> replacements)
{
var builder = new StringBuilder();
int wordStart = -1;
int wordLength = 0;
for(int i = 0; i < input.Length; i++)
{
// If the current character is white space check if we have a word to replace
if(char.IsWhiteSpace(input[i]))
{
// If wordStart is not -1 then we have hit the end of a word
if(wordStart >= 0)
{
// get the word and look it up in the dictionary
// if found use the replacement, if not keep the word.
var word = input.Substring(wordStart, wordLength);
if(replacements.TryGetValue(word, out var replace))
{
builder.Append(replace);
}
else
{
builder.Append(word);
}
}
// Make sure to reset the start and length
wordStart = -1;
wordLength = 0;
// append whatever whitespace was found.
builder.Append(input[i]);
}
// If this isn't whitespace we set wordStart if it isn't already set
// and just increment the length.
else
{
if(wordStart == -1) wordStart = i;
wordLength++;
}
}
// If wordStart is not -1 then we have a trailing word we need to check.
if(wordStart >= 0)
{
var word = input.Substring(wordStart, wordLength);
if(replacements.TryGetValue(word, out var replace))
{
builder.Append(replace);
}
else
{
builder.Append(word);
}
}
return builder.ToString();
}