这两天看到了一个题目:获取字符串中数量最多的字符。
尝试了很多种办法,比如利用List的特性,字典的特性等,甚至想从底层去寻找方法,奈何才疏学浅,最后选择了如下方法。
总体思路如下:
1.字符串是“abcdeafbacd”;
2.第一次取第一个字符‘a’和后面的字符比较,遇见‘a’就把‘a’数量+1,并把‘a’去掉;然后字符串就变成:“abcdefbcd”(少了后面的‘a’);
3.第二次取b,按照第一次的思路一步步比较;
4.一直这样比较到最后。
代码如下:
/// <summary>
/// 字符数据结构体
/// </summary>
struct CharData
{
/// <summary>
/// 字符
/// </summary>
public char target;
/// <summary>
/// 字符的数量
/// </summary>
public int count;
}
/// <summary>
/// 获取字符串中数量最多的字符
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public char? getMostChar(string str)
{
//字符串为空时,返回空
if (str == null) return null;
else
{
//1. 将字符串塞入到StringBuilder中,这样操作的过程中就不会产生额外GC
//当然也可以拆成字符数组,但是处理起来不方便;如果再转成字符链表,则会增加处理过程的复杂性。
StringBuilder strb = new StringBuilder(str);
//字符串实时长度
int len_realTime = strb.Length;
//数量最多的字符,每找到一个不同的字符就相互比较,谁的数量多,就取谁
CharData charTemp_most = new CharData();
//取出用来和其他字符比较的缓存
CharData charTemp = new CharData();
//2. 第一次遍历的目的是取出一个字符
for (int i = 0; i < len_realTime; i++)
{
//3. 取第一个字符
charTemp.target = strb[i];
//数量为1
charTemp.count = 1;
//4. 取后面的字符用来和之前取的字符比较
for (int j = i + 1; j < len_realTime; j++)
{
//5. 如果两个字符相同则进行处理
if (charTemp.target.Equals(strb[j]))
{
//5.1 字符的数量+1
charTemp.count++;
//5.2 通过字符串的StringBuilder对象,将这个相同的字符移除,这样就可以避免它参入下一次比较,提高效率
strb.Remove(j, 1);
//5.3 第二次循环的下标-1
j--;
//5.4 字符串的实时长度-1
len_realTime--;
}
}
//6. 对比一轮后,和上一次对比留下的数量最多的字符比较一下,谁数量多,就取谁
if (charTemp.count > charTemp_most.count)
{
charTemp_most = charTemp;
}
}
Debug.Log(charTemp_most.target + ":" + charTemp_most.count);
return charTemp_most.target;
}
}
如果大家有什么好的方法,一定留言告诉我。