簡體   English   中英

按子數組拆分數組

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM