这几天看到这样一个面试题,找出两个字符串中完全相同的最大字符串,比如"loveyou","likeyou"。他们匹配结果就是"eyou"。
闲的没事,写了一个,但是感觉效率太低,匹配两个一百多位的字符用了七八秒钟。只是嵌套了两层FOR循环而已。后来经过仔细推敲,感觉循环中有很多没必要循环的,很浪费效率
后来优化了几次代码,从七八秒钟,优化到了200毫秒,本来以为不能优化了 ,已经到瓶颈了。可是一时灵光一现,加了几行代码,最终变成了几毫秒就完事了。
颇有收获,好了 直接上代码。
----------------------------------------------------------------------------------------------------------------------------
namespace 匹配字符串
{
//终极版本。完结!能匹配出多于两个字符,单个字符不匹配
class Program
{
static string str = "";
static int c = 0;//计循环次数
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
string str1 = "fffffffffffffffffffFourscore and seven years ago, our fathers brought forth upon this continent a new Nationdddddddddddddddddd, conceived in Liberty, and dedicated to the proposition that all men are created equal. Now, we are engaged in a great Civil War, testing whether that Nation, or any nation so conceived and so dedicated,can long endure. We are met on a great battlefield of that war. We have come to dedicate a portion of that field as a final resting-place for those who gave their lives that Nation might live. It is altogether fitting and proper that we should do this.";
string str2 = "ffffffffffffffffffffBut, in a larger sense, we cannot dedicate, we cannot consecrate, we cannot hallow this ground. The brave men, living and dead, who struggled here, have consecrated it far above our power to add or detract. The world will little note nor long remember what we say here, but it can never forget what they did here. It is for us, the living, rather to be dedicated to the great task remaining before us; that from these honored deddddddddddddddddddddad, we take increased devotion to that cause for which they gave the last full measure of devotion; that this Nation, under GOD, shall have a new birth of freedom; and that government of the People by the People and for the People shall not perish from the earth.";
sw.Start();//启用计时器,用来计时
if (str1.Length > str2.Length)
{
string t = str1;
str1 = str2;
str2 = t;
}
List<string> list = GetStr(str1, str2);//短的在前比较快
sw.Stop();
if (list == null)
{
Console.WriteLine("没有匹配的多个字符");
}
else
{
foreach (var item in list)
{
Console.WriteLine(item);
}
Console.WriteLine("用时(毫秒):"+sw.ElapsedMilliseconds);
//Console.WriteLine(str);
Console.WriteLine("循环次数:"+c);
}
Console.ReadKey();
}
static List<string> GetStr(string str1, string str2)
{
List<string> list = new List<string>();
int i1 = str1.Length;
for (int i = 1; i < i1; i++)
{
//最后的剩余长度没匹配出的长,跳出循环
if (i1 - i - 1 < str.Length) break;
//判断前面提取跟匹配到的长度一样长的字符是否匹配。不匹配跳出这次
//这四句才是提升性能的主干
int cishu = 2;
if (str.Length != 0) { cishu = str.Length; }
if (i + cishu > i1) return null;//匹配到最后都没有 就返回null
if (!str2.Contains(str1.Substring(i, cishu))) continue;
for (int j = i1-i; j >0; j--)
{
c++;
string temp = str1.Substring(i, j);
if(str2.Contains(temp))
{
if (temp.Length > str.Length)
{
list.Clear();
str = temp;
list.Add(str);
break;//每一次匹配找出第一个,肯定是这组里最长的,因为是从后面匹配的。直接跳出这次
}
else if (temp.Length == str.Length)
{
list.Add(temp);
}
}
}
}
return list;
}
}
}
--------------------------------------------------------------------------------------------------
ffffffffffffffffff
dddddddddddddddddd
dedicated to the
用时(毫秒):4
循环次数:1467
-------------------------------------------------------------------------------------------------------
代码就是这么多。注释什么的也都有,只要思想就是从后面匹配,匹配时先判断前面2位是否匹配,不匹配后面再循环也就没意义了。

浙公网安备 33010602011771号