[英]Split array by subarrays
我有一個數組,例如
char[] myArr = {'a', 'b', '1', '2', 'c', 'd', '1', '2', 'e', 'f'}
在這種情況下,定界子序列為{'1','2'}。
我想按此順序拆分數組,並得到數組列表:
{'a', 'b'}
{'c', 'd'}
{'e', 'f'}
最快的方法是什么?
new string(myArr)
.Split(new[] { "12" }, StringSplitOptions.None)
.Select(s => s.ToCharArray())
.ToList();
或者,如果您說“列表”是指“數組”,那么
new string(myArr)
.Split(new[] { "12" }, StringSplitOptions.None)
.Select(s => s.ToCharArray())
.ToArray();
另外,您可能更喜歡StringSplitOptions.RemoveEmptyEntries
。
但是,如果這是家庭作業,則此解決方案可能是不可接受的。
當您詢問處理字節時,這是為此目的的一種改編。 首先,有幾種方法可以將字節數組轉換為字符串並返回:
string ByteArrayToString(byte[] arr)
{
char[] charArray = arr.Select(b => (char)b).ToArray();
return new string(charArray);
}
byte[] StringToByteArray(string s)
{
//this method maps each char in the string to a single output byte;
//all chars should be in the range 0 to 255. The checked
//conversion will catch any data that violates this requirement.
return s.Select(c => checked ( (byte)c )).ToArray();
}
現在,示例代碼片段:
byte[] myArr = Whatever();
byte[] myDelim = WhateverElse();
string sourceData = ByteArrayToString(myArr);
string delimiter = ByteArrayToString(myDelim);
string[] splitData = sourceData.Split(new [] { delimiter }, StringSplitOptions.None);
byte[][] result = splitData.Select(StringToByteArray);
我將從使用ForEach循環和Char.IsLetter函數開始 。 向我們顯示一些代碼,我們將為您提供幫助。
由於您正在使用字符,因此可以將myArr
數組轉換為字符串,並使用C#的String.Split
方法。 結果將是一個字符串數組,當您完成所有操作后,您可以將它們分成單個字符,這是一個示例:
char[] myArr = {'a', 'b', '1', '2', 'c', 'd', '1', '2', 'e', 'f'};
var myArrFlattened = "";
myArr.ToList().ForEach(c => myArrFlattened += c.ToString());
var separators = new string[] {"12"}; // put your sequences of characters here as a string
myArrFlattened.Split(separators, StringSplitOptions.None);
最后一行的值是以下數組: {"ab", "cd", "ef"}
,此代碼不會將字符串分成字符列表,為此,您可以使用foreach
並應用String.ToCharArray
函數。
string s = new String(myArr);
string[] parts = s.Split(new string[] {"12"}, StringSplitOptions.None);
然后,您可以將結果轉換為char數組
var list = new List<char[]>();
foreach (string part in parts) {
list.Add(part.ToCharArray());
}
編輯:當您需要通用方法時,這里有兩個通用解決方案。
如果子數組的長度始終相同,則可以這樣:
public List<T[]> GetSubArrays<T>(T[] array)
{
const int LengthOfSpearator = 2, LengthOfSubArray = 2;
const int LengthOfPattern = LengthOfSpearator + LengthOfSubArray;
var list = new List<T[]>();
for (int i = 0; i <= array.Length - LengthOfSubArray; i += LengthOfPattern) {
T[] subarray = new T[LengthOfSubArray];
Array.Copy(array, i, subarray, 0, LengthOfSubArray);
list.Add(subarray);
}
return list;
}
如果子陣列的長度是可變的,則算法變得更加復雜。 我們還必須將通用參數限制為IEquatable,以便能夠進行比較。
public List<T[]> GetSubArrays<T>(T[] array, T[] separator)
where T : IEquatable<T>
{
int maxSepIndex = array.Length - separator.Length;
var list = new List<T[]>();
for (int i = 0; i <= array.Length; ) {
// Get index of next separator or array.Length if none is found
int sepIndex;
for (sepIndex = i; sepIndex <= maxSepIndex; sepIndex++) {
int k;
for (k = 0; k < separator.Length; k++) {
if (!array[sepIndex + k].Equals(separator[k])) {
break;
}
}
if (k == separator.Length) { // Separator found at sepIndex
break;
}
}
if (sepIndex > maxSepIndex) { // No separator found, subarray goes until end.
sepIndex = array.Length;
}
int lenSubarray = sepIndex - i;
T[] subarray = new T[lenSubarray];
Array.Copy(array, i, subarray, 0, lenSubarray);
list.Add(subarray);
i = sepIndex + separator.Length;
}
return list;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.