That's basically what you need to do - or at least, it's the easiest solution. All you'd be "wasting" is the cost of n method invocations - you won't actually be checking any case twice, if you think about it. (IndexOf will return as soon as it finds the match, and you'll keep going from where it left off.)
Здесь рекурсивная реализация (указанной выше идеи) в качестве метода расширения, имитируя формат метода каркаса (ов):
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));
}
}
}
похоже: http://stackoverflow.com/a/9908392/1305911 – JNF 2012-10-24 10:58:55
Я бы использовал регулярные выражения для этого, тогда вам нужно оптимальное способ сопоставления строки внутри строки. Это в одной из прекрасных DSL, которые мы все должны использовать, когда это возможно. [Пример] (http://www.regular-expressions.info/dotnet.html «Ссылка») в VB.net код почти такой же, как на C#. – bovium 2008-10-09 11:09:59
Я бы поместил хорошие деньги на версию регулярных выражений значительно сложнее, чем «продолжить цикл и сделать простой String.IndexOf». Регулярные выражения имеют свое место, но не должны использоваться, когда существуют более простые альтернативы. – 2008-10-09 12:06:10