题目:将字符串分割成单个字符,并按一定顺序输出
承接上一篇博文中的简陋分割,前一篇文章中只是针对的、临时的解决方法,为了能具有适用性,我换了一个方式。
因为菜鸟能力不高,为了能让他人快速了解,我在这里注明以下几点:
- 字符仅限中英文,这里没有对标点符与特殊符号进行限制,如‘\n’ ‘\t’等,但是后续会对特殊符号加以限制输入
- 为了以后能扩展,这里使用了字典的想法。
- 为了能让菜鸟的想法能更具有普遍性,所以代码中有C与C#混和的部分(想法),请勿吐槽,还是要归咎于菜鸟的懒惰,所以在需要使用复杂的东西时,菜鸟也就是知其然不知其所以然,例如集合
个人代码:
/// <summary>
/// 为了能体现算法的普遍性,这里使用了结构体而非对象(PS:其实都一样提供了封装的概念)
/// 将每个字符视为字
/// </summary>
struct word
{
public char character;
public int count;
public string type;
}
class Char_Frequency_Update
{
public Char_Frequency_Update()
{
//为了尽量不浪费空间,这里不得不使用集合list,不算很适合
List<word> dictionary = new List<word>();
string text = "aabsbacdbda";
//string text = "吃葡萄不吐葡萄皮不吃葡萄倒吐葡萄皮";
//获取数据源数组
char[] tarr=text.ToCharArray();
//使用index数组来表示字符是否占位
int[] index = new int[tarr.Length];
//遍历数据源
for(int i = 0; i < tarr.Length; i++)
{
//这里需要改进,面对庞大的数据时,如依次判断100000个占位,效率有点浪费
//查看index数组对应下标,判断该字符是否被占
if (index[i] == 0)
{
#region 创建字对象,并将其占据
word tp = new word();
tp.character = tarr[i];
tp.count = 1;
tp.type = "letter";
index[i] = 1;
#endregion
/*
* 这里依次遍历从现在的位置到数据源数据结束
* 有出现重复的字,则count++,并占位
*/
for (int j = i; j < tarr.Length; j++)
{
if (index[j] == 0 && tarr[j].Equals(tarr[i]))
{
tp.count += 1;
index[j] = 1;
}
}
//添加到字典
dictionary.Add(tp);
}
}
//未排序的字典
foreach(word pp in dictionary)
{
Console.WriteLine("{0}:{1}",pp.character,pp.count);
}
Console.WriteLine("====================");
//字典依照 出现次数、字母表顺序 排序
dictionary.Sort(new AlphabatSort());
//排序后的字典
foreach (word pp in dictionary)
{
Console.WriteLine("{0}:{1}", pp.character, pp.count);
}
Console.ReadKey();
}
}
class AlphabatSort : IComparer<word>
{
/*
*由于时间与水平关系,没有办法自己完全写一个排序比较的轮子
* 所以暂时借用了.NET提供的排序方法,意外发现了原来List.sort,
* 是使用的二叉树的结构,这个后面再慢慢研究,这里就先拿来用着
*/
public int Compare(word x, word y)
{
#region 这里比较次数
//int key = x.count - y.count;升序
int key = y.count - x.count;//降序
#endregion
//出现字数相同时,比较字符顺序,这里区分大小写
if (key == 0)
{
key = x.character > y.character ? 1 : -1;
}
return key;
}
}