簡體   English   中英

C#-將字符串中特定字符的索引添加到整數列表

[英]C# - Adding indexes of specific chars in a string to a list of integers

尋找有關如何獲取以下代碼以生成longString中每個空格和連字符的索引列表的longString

每當我運行下面的語句時,它只會在我的整數列表中加5。 給定我在以下示例中使用的字符串,我試圖使它收集5、11、14、24和27。

static void Main(string[] args)
    {
        string longString = "hello world my user-name is stevieray8450";
        int longStringLength = longString.Length;
        char whiteSpace = ' ';
        char hyphen = '-';

        // list to store all indexes of white space
        List<int> specialIndexes = new List<int>();

        foreach (char c in longString)
        {
            if (c.Equals(whiteSpace) || c.Equals(hyphen))
            {
                specialIndexes.Add(longString.IndexOf(c));
            }
        }

我想知道為什么我的foreach循環中的char c 每次都會對我的specialIndexes.Add(longString.IndexOf(c)); 的空格每次求值為5的specialIndexes.Add(longString.IndexOf(c)); 聲明。

任何想法,意見,評論歡迎:)謝謝!

您應該改用for循環,以便直接獲取索引:

for(int i =0; i < longString.length; i++)
{
    if (longString[i].Equals(whiteSpace) || longString[i].Equals(hyphen))
    {
         specialIndexes.Add(i);
    }
}

當然,有人會為您提供一些LINQ代碼,它們將以更少的代碼完成相同的任務。 等等...

當您的c = ' '始終為5時, longString.IndexOf(c)將始終為IndexOf僅返回其參數首次出現的索引。

public int IndexOf(char value)

如果找到該字符,則從零開始的索引位置,否則為-1。

請記住,char是一個value-type因此默認情況下,您正在使用副本。

當您調用index時,您將獲得字符串中第一個匹配項的索引

https://msdn.microsoft.com/zh-CN/library/k8b1470s(v=vs.110).aspx

您可以嘗試:

string longString = "hello world my user-name is stevieray8450";
int longStringLength = longString.Length;
char whiteSpace = ' ';
char hyphen = '-';
int index = 0;

// list to store all indexes of white space
List<int> specialIndexes = new List<int>();

foreach (char c in longString)
{
    if (c.Equals(whiteSpace) || c.Equals(hyphen))
    {
        specialIndexes.Add(index);
    }
    index++;
}

下一行...

specialIndexes.Add(longString.IndexOf(c));

...將返回第一次出現的c的索引,而不是當前的索引。 在示例字符串中,第一個空格或連字符為位置5處的空格。

解決此問題的最佳方法是使用for循環,並將計數器值存儲為索引。

這是因為char類型是一個值類型,並且IndexOf返回第一次出現的索引。 就是說,它將返回5作為結果。

您需要將自己的計數器添加到foreach循環中或在for循環並在其中使用其索引。

static void Main(string[] args) {
    string longString = "hello world my user-name is stevieray8450";
    HashSet<char> desiredChars = new HashSet<char> { ' ', '-' };

    List<int> specialIndexes = longString
       .Select((char, i) => new KeyValuePair<char, int>(char, i))
       .Where(kvp => desiredChars.Contains(kvp.Key))
       .Select(kvp => kvp.Value)
       .ToList();
}

這是您的代碼的另一個版本:

string longString = "hello world my user-name is stevieray8450";
int longStringLength = longString.Length;
char whiteSpace = ' ';
char hyphen = '-';

// list to store all indexes of white space
List<int> specialIndexes = new List<int>();

int index = 0;
do
{
       index = longString.IndexOf(whiteSpace, index);
       if (index > -1)
       {
             specialIndexes.Add(index);
             index++;
       }

} while (index != -1);

我更喜歡可以使用它們的LINQ解決方案。 LINQ的問題在於索引不會結轉到下一條語句。 要了解我的意思,請考慮以下幾點:

var longString = "hello world my user-name is stevieray8450";

var badIndices = longString
    .Where(c => c == ' ')
    .Select((c, i) => i)
    .ToArray();

Console.WriteLine($"[bad!] found ' ' at indices: {string.Join(", ", badIndices)}");

雖然看起來結果應該5, 11, 14, 24, 27 ,但實際結果將是:

[壞!]在索引:0、1、2、3、4處發現了''

為了繼承正確的索引,我們必須即時創建一個中間anonymous type

    var indices = longString
        .Select((c, i) => new
        {
            idx = i,
            val = c
        })
        .Where(ci => ci.val == ' ')
        .Select(ci => ci.idx)
        .ToArray();

    Console.WriteLine($"[good] found ' ' at indices: {string.Join(", ", indices)}");

一旦習慣了它並沒有那么糟糕,我更喜歡它而不是編寫自己的循環。 結果是:

[good]在指數:5、11、14、24、27處發現了''

但是,在這種特殊情況下, for-loop效率要高得多,並且完成時間約為LINQ的1/5。

這個答案中 ,您可以將for循環與IndexOf的(char,int)重載結合使用,以提供一個簡潔的解決方案:

var specialIndexes = new List<int>();
for (int i = s.IndexOf(' '); i > -1; i = s.IndexOf(' ', i + 1))
{
    specialIndexes.Add(i);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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