Way to check repeated messages within a string?
The messages are exact dont need to worry about variation or simbols in between, right now I am just looking for a efficient way that can check messages like the below.
I have a message like:
string msg = "This is a small message !";
And I would like to check if that messa开发者_JAVA技巧ge was sent repeated times in the same string like this:
string msg = "This is a small message !This is a small message !";
or:
string msg = "This is a small message !This is a small message !This is a small message !";
or:
string msg = "This is a small message !This is a small message !This is a small message !This is a small message !This is a small message !";
I have a LinkedList<string>
that stores the last 3 messages received and along with those last 3 message I would like to match the current messages to see if it is either equal to one of the current store messages or a repetition of any.
foreach (string item in myListOfMessages)
{
if (string.Equals(msg, item))
{
// the message matchs one of the stored messages
}
else if (msg.Lenght == (item.Lenght * 2) && string.Equals(msg, string.Concat(item, "", item)))
{
// the message is a repetition, and ofc only works when some one sends the message twice in the same string
}
}
Like I showed in the examples, the repetition could be quite large, also I am not sure if the method I presented above is the best one for what I need. It was the first idea that came to my mind but soon after I realised that it would produce a lot more work that way.
Linq to the rescue:
string msg = "This is a small message !";
string otherMsg = "This is a small message !This is a small message !This is a small message !This is a small message !This is a small message !";
bool isRepeated = Enumerable.Range(0, otherMsg.Length / msg.Length)
.Select(i => otherMsg.Substring(i * msg.Length, msg.Length))
.All( x => x == msg);
This approach basically takes a sub string of the length of the first message and compares each chunk with the original message.
Wrapped in a method with some pre-checking:
public bool IsRepeated(string msg, string otherMsg)
{
if (otherMsg.Length < msg.Length || otherMsg.Length % msg.Length != 0)
return false;
bool isRepeated = Enumerable.Range(0, otherMsg.Length / msg.Length)
.Select(i => otherMsg.Substring(i * msg.Length, msg.Length))
.All(x => x == msg);
return isRepeated;
}
Edit:
Above approach will generate unnecessary strings that will have to be gc'ed - a much more efficient and faster solution:
public bool IsRepeated(string msg, string otherMsg)
{
if (otherMsg.Length < msg.Length || otherMsg.Length % msg.Length != 0)
return false;
for (int i = 0; i < otherMsg.Length; i++)
{
if (otherMsg[i] != msg[i % msg.Length])
return false;
}
return true;
}
You could try using a Regular Expression
string msg = "This is a small message !";
string Input = "This is a small message !This is a small message !";
System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(msg);
System.Text.RegularExpressions.MatchCollection Matches = r.Matches(Input);
int Count = Matches.Count; //Count = 2
private int countRepeats(string msg, string item)
{
if(string.Replace(msg, item).Length > 0)
return 0;
return msg.Length / item.Length;
}
static void Main(string[] args)
{
string msg = "This is a small message !This is a small message !This is a small message !";
string substring = "This is a small message !";
string[] split = msg.Split(new string[] { substring }, StringSplitOptions.None);
Console.WriteLine(split.Length - 1);
foreach (string splitPart in split)
{
if (!String.IsNullOrEmpty(splitPart))
Console.WriteLine("Extra info");
}
}
精彩评论