根據指定字符集拆分任意字串
題目真不知道怎麼寫。。我經常自己做一些小工具,所以並沒啥系統的東西可寫,這也並不是我想寫系統的東西,而且看別人寫的高大上的東西我也一點都不羨慕,真的
具體是這樣,有一個列表,裡面存放的是一些不重複的字元,假定這些字元就是我需要找出的,或者說在我這個工具中,我需要在一個任意字串中分別找出字元列表中有的和沒有的,並拆分成小的字串。說著這麼多,我成功把自己說糊塗了。
舉個栗子更好說明我的意圖:
//指定的字符集
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
});
}
這樣整個就做完了。
當然這樣的需求我估計應該沒人會碰到,而且在我寫的工具裡都封裝過了,就不貼出完整程式碼了。
測試結果(不要在意細節)(不要在意內容)(不要在意指定的字符集)(啥都不要在意):