एक स्ट्रिंग के n वें घटना के सूचकांक प्राप्त करें?

वोट
96

जब तक मैं एक स्पष्ट निर्मित विधि याद आ रही है, तेज तरीका पाने के लिए क्या है n वें एक स्ट्रिंग के भीतर एक स्ट्रिंग की घटना?

मुझे लगता है कि मैं पाश सकता है indexOf पाश से प्रत्येक यात्रा पर अपनी शुरुआत सूचकांक अपडेट करके विधि। लेकिन यह इस तरह से कर रही है मेरे लिए बेकार लगता है।

09/10/2008 को 11:20
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


10 जवाब

वोट
51

या कम से कम, यह सबसे आसान समाधान है - वह मूल रूप से आप क्या करने की जरूरत है। सभी चाहते हैं कि आप "बर्बाद कर" जा n विधि आमंत्रण की लागत है - आप वास्तव में नहीं किसी भी मामले की जाँच की जाएगी दो बार, अगर आप इसके बारे में सोचते हैं। (IndexOf जैसे ही यह मैच पाता है वापस आ जाएगी, और आप जहां यह दूर छोड़ दिया से जा रहा रखेंगे।)

09/10/2008 को 11:26
का स्रोत उपयोगकर्ता

वोट
99

आप वास्तव में नियमित अभिव्यक्ति इस्तेमाल कर सकते हैं /((s).*?){n}/-स्ट्रिंग के एन-वीं घटना के लिए खोज करने के लिए s

सी # में यह इस प्रकार दिखाई देंगे:

public static class StringExtender
{
    public static int NthIndexOf(this string target, string value, int n)
    {
        Match m = Regex.Match(target, "((" + Regex.Escape(value) + ").*?){" + n + "}");

        if (m.Success)
            return m.Groups[2].Captures[n - 1].Index;
        else
            return -1;
    }
}

नोट: मैं जोड़ लिया है Regex.Escapeमूल समाधान के लिए जो regex इंजन के लिए विशेष अर्थ नहीं होता पात्रों खोज अनुमति देने के लिए।

09/10/2008 को 15:01
का स्रोत उपयोगकर्ता

वोट
14
private int IndexOfOccurence(string s, string match, int occurence)
{
    int i = 1;
    int index = 0;

    while (i <= occurence && (index = s.IndexOf(match, index + 1)) != -1)
    {
        if (i == occurence)
            return index;

        i++;
    }

    return -1;
}

या सी में # विस्तार तरीकों के साथ

public static int IndexOfOccurence(this string s, string match, int occurence)
{
    int i = 1;
    int index = 0;

    while (i <= occurence && (index = s.IndexOf(match, index + 1)) != -1)
    {
        if (i == occurence)
            return index;

        i++;
    }

    return -1;
}
07/10/2009 को 05:39
का स्रोत उपयोगकर्ता

वोट
17

या कम से कम, यह सबसे आसान समाधान है - वह मूल रूप से आप क्या करने की जरूरत है। सभी चाहते हैं कि आप "बर्बाद कर" जा n विधि आमंत्रण की लागत है - आप वास्तव में नहीं किसी भी मामले की जाँच की जाएगी दो बार, अगर आप इसके बारे में सोचते हैं। (IndexOf जैसे ही यह मैच पाता है वापस आ जाएगी, और आप जहां यह दूर छोड़ दिया से जा रहा रखेंगे।)

यहाँ (ऊपर की पुनरावर्ती कार्यान्वयन है विचार ) एक विस्तार पद्धति के रूप में, ढांचे विधि (ओं) का प्रारूप mimicing:

public static int IndexOfNth(this string input,
                             string value, int startIndex, int nth)
{
    if (nth < 1)
        throw new NotSupportedException("Param 'nth' must be greater than 0!");
    if (nth == 1)
        return input.IndexOf(value, startIndex);
    var idx = input.IndexOf(value, startIndex);
    if (idx == -1)
        return -1;
    return input.IndexOfNth(value, idx + 1, --nth);
}

इसके अलावा, यहाँ कुछ (MBUnit) इकाई परीक्षण है कि आप (यह सही है साबित करने के लिए) में मदद कर सकते हैं:

using System;
using MbUnit.Framework;

namespace IndexOfNthTest
{
    [TestFixture]
    public class Tests
    {
        //has 4 instances of the 
        private const string Input = "TestTest";
        private const string Token = "Test";

        /* Test for 0th index */

        [Test]
        public void TestZero()
        {
            Assert.Throws<NotSupportedException>(
                () => Input.IndexOfNth(Token, 0, 0));
        }

        /* Test the two standard cases (1st and 2nd) */

        [Test]
        public void TestFirst()
        {
            Assert.AreEqual(0, Input.IndexOfNth("Test", 0, 1));
        }

        [Test]
        public void TestSecond()
        {
            Assert.AreEqual(4, Input.IndexOfNth("Test", 0, 2));
        }

        /* Test the 'out of bounds' case */

        [Test]
        public void TestThird()
        {
            Assert.AreEqual(-1, Input.IndexOfNth("Test", 0, 3));
        }

        /* Test the offset case (in and out of bounds) */

        [Test]
        public void TestFirstWithOneOffset()
        {
            Assert.AreEqual(4, Input.IndexOfNth("Test", 4, 1));
        }

        [Test]
        public void TestFirstWithTwoOffsets()
        {
            Assert.AreEqual(-1, Input.IndexOfNth("Test", 8, 1));
        }
    }
}
22/03/2011 को 04:34
का स्रोत उपयोगकर्ता

वोट
-3

यह कर सकते हैं:

Console.WriteLine(str.IndexOf((@"\")+2)+1);
08/07/2012 को 08:05
का स्रोत उपयोगकर्ता

वोट
1

शायद यह भी साथ काम करने के अच्छा होगा String.Split(), विधि और देखें कि क्या अनुरोध किया घटना सरणी में है अगर आप सूचकांक पर सूचकांक, लेकिन मूल्य की जरूरत नहीं है

13/05/2014 को 10:08
का स्रोत उपयोगकर्ता

वोट
1

कुछ बेंच मार्किंग के बाद, इस सरल और सबसे effcient समाधान लगता है

public static int IndexOfNthSB(string input,
             char value, int startIndex, int nth)
        {
            if (nth < 1)
                throw new NotSupportedException("Param 'nth' must be greater than 0!");
            var nResult = 0;
            for (int i = startIndex; i < input.Length; i++)
            {
                if (input[i] == value)
                    nResult++;
                if (nResult == nth)
                    return i;
            }
            return -1;
        }
08/08/2018 को 19:58
का स्रोत उपयोगकर्ता

वोट
0

FTW System.ValueTuple:

var index = line.Select((x, i) => (x, i)).Where(x => x.Item1 == '"').ElementAt(5).Item2;

एक समारोह लेखन कि से होमवर्क है

19/08/2018 को 00:07
का स्रोत उपयोगकर्ता

वोट
0

टॉड का जवाब कुछ हद तक सरल किया जा सकता।

using System;

static class MainClass {
    private static int IndexOfNth(this string target, string substring,
                                        int seqNr, int startIdx = 0)
    {
        if (seqNr < 1)
        {
            throw new IndexOutOfRangeException("Parameter 'nth' must be greater than 0.");
        }

        var idx = target.IndexOf(substring, startIdx);

        if (seqNr == 1) { return idx; }

        return target.IndexOfNth(substring, --seqNr, ++idx); // skip
    }

    static void Main () {
        Console.WriteLine ("abcbcbcd".IndexOfNth("bc", 2));
    }
}

उत्पादन

3

16/08/2019 को 18:39
का स्रोत उपयोगकर्ता

वोट
0

या के साथ कुछ इस तरह है, जबकि पाश करना

 private static int OrdinalIndexOf(string str, string substr, int n)
    {
        int pos = -1;
        do
        {
            pos = str.IndexOf(substr, pos + 1);
        } while (n-- > 0 && pos != -1);
        return pos;
    }
22/12/2019 को 00:48
का स्रोत उपयोगकर्ता

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more