题目真不知道怎么写。。我经常自己做一些小工具,所以并没啥系统的东西可写,这也并不是我想写系统的东西,而且看别人写的高大上的东西我也一点都不羡慕,真的
具体是这样,有一个列表,里面存放的是一些不重复的字符,假定这些字符就是我需要找出的,或者说在我这个工具中,我需要在一个任意字符串中分别找出字符列表中有的和没有的,并拆分成小的字符串。说着这么多,我成功把自己说糊涂了。
举个栗子更好说明我的意图:
//指定的字符集
char[] data = new char[]
{
'a', 'c', 'e'
};
然后有个任意字符串:
string input = "eadshafajhkjacccacaesdmf";
我要做的就是将其拆分为:
ea
dsh
a
f
a
jhkj
acccacae
sdmf
oh, this is so boring.
同事对我的评价基本都是“喜欢把简单的事情复杂化”。
接下来就开始介绍我是如何把简单的事情复杂化的。
(tips:以下代码片段均以减慢运行速度、占用更多内存、降低程序性能为目的进行编写的)
首先获取指定列表中不存在的字符在给定字符串中的位置
/// <summary>
/// 获取指定列表中不存在的字符在给定字符串中的位置
/// </summary>
/// <param name="input">给定的字符串</param>
/// <param name="source">指定的列表</param>
public List<int> GetFailedLocations(string input, char[] source)
{
if (string.IsNullOrEmpty(input))
{
return null;
}
List<int> failedLocs = new List<int>();
try
{
List<char> failedtemp = new List<char>();//为了增加内存占用,创建一个存放已找出的不存在的字符集缓存
int index = 0;
foreach (var value in input)
{
if (failedtemp.Contains(value))
{
failedLocs.Add(index);
}
else
{
if (!source.Contains(value))
{
failedtemp.Add(value);
failedLocs.Add(index);
}
}
index++;
}
}
catch { throw; }
return failedLocs;
}
新建一个类用来存放分类之后的字符串信息:
public class Sentence
{
public int Order { get; set; }//在原始字符串中的次序
public string Data { get; set; }//分割出的字符串信息
public bool Failed { get; set; }//是否在指定字符集中存在
public override string ToString()
{
return this.Data;
}
}
这里要说明的是,如果在给定的字符串中,有连续多个字符在指定的字符集中存在,那就把它们连接成一个字符串而不是单个字符。
然后,
如果全部都存在,即之前得到的存放不存在字符序号的列表数量为0,那么就原样放进类中
Sentence sentence = new Sentence()
{
Order = 0,
Data = input,
Failed = false
};
否则进行如下处理:
获取在给定字符串中不存在的【连续】字符的起始位置及长度:
//startindex, length
Dictionary<int, int> loctemp = new Dictionary<int, int>();
int index = -1;
int lastloc = -1;
foreach (var loc in failedLocs)
{
if (loc != index)
{
loctemp.Add(loc, 1);
index = loc;
lastloc = loc;
}
else
{
loctemp[lastloc]++;
}
index++;
}
上面这些代码有点绕,如果同事们看了一定又要说:我靠!这么复杂!你就不能写简单点吗?
那我解释下,如果出现两个及以上连续字符,那么后一个的次序一定是前一个的次序+1,如果这个【联系】断掉之后,就证明连续的部分已经结束,需要重新开始判断是否连续了。 lastloc 用来记录【可能】连续的字符串的首位次序,然后放进一个字典中,如果后一个次序刚好是前一个次序+1,那么对应的【重复次数】就要增加1
(肯定有十分简单的方法,但我只能想到这种)
好了,现在已经得到不存在的字符在给定字符串中的起始位置和长度,接下来进行归类。
思路是,对上一步得到的位置长度列表每循环一次,就把键之前的字符串取出来放到一边,把键和它对应长度的字符串取出来放到另一边。
这样循环结束后,如果还剩下字符串没处理,那这段字符串一定就是由指定字符集中没有出现过的字符组成的。
这样就全部划分完了。
具体实现:
index = 0;
lastloc = 0;
foreach (var key in loctemp.Keys)
{
if (key > lastloc)//其实这里的判断只需要在开头第一遍循环中加入,对应的是字符串开头就匹配到了的情况
{
result.Add(new Sentence()
{
Order = index,
Data = input.Substring(lastloc, key - lastloc),
Failed = false
});
index++;
}
result.Add(new Sentence()
{
Order = index,
Data = input.Substring(key, loctemp[key]),
Failed = true
});
lastloc = key + loctemp[key];
index++;
}
if (lastloc < input.Length)
{
result.Add(new Sentence()
{
Order = index,
Data = input.Substring(lastloc),
Failed = false
});
}
这样整个就做完了。
当然这样的需求我估计应该没人会碰到,而且在我写的工具里都封装过了,就不贴出完整代码了。
测试结果(不要在意细节)(不要在意内容)(不要在意指定的字符集)(啥都不要在意):