C #에서 더 큰 문자열에서 하위 문자열의 모든 위치 찾기
구문 분석해야하는 큰 문자열이 있고의 모든 인스턴스를 찾아서 extract"(me,i-have lots. of]punctuation
각각의 인덱스를 목록에 저장해야합니다.
따라서이 문자열 조각이 더 큰 문자열의 시작과 중간에 있다고 가정하면 둘 다 발견되고 해당 인덱스가 List
. 그리고 그것이 무엇이든 List
포함 0
하고 다른 색인을 포함 합니다.
나는 주위 놀았 던, 그리고는 string.IndexOf
않습니다 거의 내가 찾고, 나는 몇 가지 코드를 작성했습니다 무엇을 - 그러나 그것은 작동하지 않습니다와 내가 잘못 정확히 알아낼 수 없었습니다 :
List<int> inst = new List<int>();
int index = 0;
while (index < source.LastIndexOf("extract\"(me,i-have lots. of]punctuation", 0) + 39)
{
int src = source.IndexOf("extract\"(me,i-have lots. of]punctuation", index);
inst.Add(src);
index = src + 40;
}
inst
= 목록source
= 큰 문자열
더 좋은 아이디어가 있습니까?
다음은 이에 대한 확장 방법의 예입니다.
public static List<int> AllIndexesOf(this string str, string value) {
if (String.IsNullOrEmpty(value))
throw new ArgumentException("the string to find may not be empty", "value");
List<int> indexes = new List<int>();
for (int index = 0;; index += value.Length) {
index = str.IndexOf(value, index);
if (index == -1)
return indexes;
indexes.Add(index);
}
}
이것을 정적 클래스에 넣고를 사용하여 네임 스페이스를 가져 using
오면 모든 문자열에 메서드로 표시되며 다음과 같이 할 수 있습니다.
List<int> indexes = "fooStringfooBar".AllIndexesOf("foo");
확장 방법에 대한 자세한 내용은 http://msdn.microsoft.com/en-us/library/bb383977.aspx 를 참조하십시오 .
반복자를 사용하여도 동일합니다.
public static IEnumerable<int> AllIndexesOf(this string str, string value) {
if (String.IsNullOrEmpty(value))
throw new ArgumentException("the string to find may not be empty", "value");
for (int index = 0;; index += value.Length) {
index = str.IndexOf(value, index);
if (index == -1)
break;
yield return index;
}
}
내장 된 RegEx 클래스를 사용하지 않는 이유 :
public static IEnumerable<int> GetAllIndexes(this string source, string matchString)
{
matchString = Regex.Escape(matchString);
foreach (Match match in Regex.Matches(source, matchString))
{
yield return match.Index;
}
}
표현식을 재사용해야하는 경우 컴파일하고 어딘가에 캐시하십시오. 재사용 사례에 대한 다른 오버로드에서 matchString 매개 변수를 Regex matchExpression으로 변경합니다.
LINQ 사용
public static IEnumerable<int> IndexOfAll(this string sourceString, string subString)
{
return Regex.Matches(sourceString, subString).Cast<Match>().Select(m => m.Index);
}
세련된 버전 + 지원을 무시하는 케이스 :
public static int[] AllIndexesOf(string str, string substr, bool ignoreCase = false)
{
if (string.IsNullOrWhiteSpace(str) ||
string.IsNullOrWhiteSpace(substr))
{
throw new ArgumentException("String or substring is not specified.");
}
var indexes = new List<int>();
int index = 0;
while ((index = str.IndexOf(substr, index, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)) != -1)
{
indexes.Add(index++);
}
return indexes.ToArray();
}
public List<int> GetPositions(string source, string searchString)
{
List<int> ret = new List<int>();
int len = searchString.Length;
int start = -len;
while (true)
{
start = source.IndexOf(searchString, start + len);
if (start == -1)
{
break;
}
else
{
ret.Add(start);
}
}
return ret;
}
다음과 같이 호출하십시오.
List<int> list = GetPositions("bob is a chowder head bob bob sldfjl", "bob");
// list will contain 0, 22, 26
@Matti Virkkunen의 좋은 답변
public static List<int> AllIndexesOf(this string str, string value) {
if (String.IsNullOrEmpty(value))
throw new ArgumentException("the string to find may not be empty", "value");
List<int> indexes = new List<int>();
for (int index = 0;; index += value.Length) {
index = str.IndexOf(value, index);
if (index == -1)
return indexes;
indexes.Add(index);
index--;
}
}
그러나 이것은 AOOAOOA와 같은 테스트 케이스를 다룹니다.
AOOA 및 AOOA
출력 0 및 3
정규식없이 문자열 비교 유형 사용 :
string search = "123aa456AA789bb9991AACAA";
string pattern = "AA";
Enumerable.Range(0, search.Length)
.Select(index => { return new { Index = index, Length = (index + pattern.Length) > search.Length ? search.Length - index : pattern.Length }; })
.Where(searchbit => searchbit.Length == pattern.Length && pattern.Equals(search.Substring(searchbit.Index, searchbit.Length),StringComparison.OrdinalIgnoreCase))
.Select(searchbit => searchbit.Index)
그러면 {3,8,19,22}가 반환됩니다. 빈 패턴은 모든 위치와 일치합니다.
여러 패턴의 경우 :
string search = "123aa456AA789bb9991AACAA";
string[] patterns = new string[] { "aa", "99" };
patterns.SelectMany(pattern => Enumerable.Range(0, search.Length)
.Select(index => { return new { Index = index, Length = (index + pattern.Length) > search.Length ? search.Length - index : pattern.Length }; })
.Where(searchbit => searchbit.Length == pattern.Length && pattern.Equals(search.Substring(searchbit.Index, searchbit.Length), StringComparison.OrdinalIgnoreCase))
.Select(searchbit => searchbit.Index))
그러면 {3, 8, 19, 22, 15, 16}이 반환됩니다.
적어도 두 개의 제안 된 솔루션이 겹치는 검색 히트를 처리하지 않는다는 것을 알았습니다. 녹색 확인 표시가있는 항목은 확인하지 않았습니다. 다음은 겹치는 검색 적중을 처리하는 것입니다.
public static List<int> GetPositions(this string source, string searchString)
{
List<int> ret = new List<int>();
int len = searchString.Length;
int start = -1;
while (true)
{
start = source.IndexOf(searchString, start +1);
if (start == -1)
{
break;
}
else
{
ret.Add(start);
}
}
return ret;
}
더 큰 문자열 내에서 문자열의 여러 인스턴스를 찾는 데 사용한 코드를 기반으로하면 코드는 다음과 같습니다.
List<int> inst = new List<int>();
int index = 0;
while (index >=0)
{
index = source.IndexOf("extract\"(me,i-have lots. of]punctuation", index);
inst.Add(index);
index++;
}
public static Dictionary<string, IEnumerable<int>> GetWordsPositions(this string input, string[] Susbtrings)
{
Dictionary<string, IEnumerable<int>> WordsPositions = new Dictionary<string, IEnumerable<int>>();
IEnumerable<int> IndexOfAll = null;
foreach (string st in Susbtrings)
{
IndexOfAll = Regex.Matches(input, st).Cast<Match>().Select(m => m.Index);
WordsPositions.Add(st, IndexOfAll);
}
return WordsPositions;
}
@csam 은 이론상 정확하지만 그의 코드는 준수 하지 않고
public static IEnumerable<int> IndexOfAll(this string sourceString, string matchString)
{
matchString = Regex.Escape(matchString);
return from Match match in Regex.Matches(sourceString, matchString) select match.Index;
}
이 예제를 찾아서 함수에 통합했습니다.
public static int solution1(int A, int B)
{
// Check if A and B are in [0...999,999,999]
if ( (A >= 0 && A <= 999999999) && (B >= 0 && B <= 999999999))
{
if (A == 0 && B == 0)
{
return 0;
}
// Make sure A < B
if (A < B)
{
// Convert A and B to strings
string a = A.ToString();
string b = B.ToString();
int index = 0;
// See if A is a substring of B
if (b.Contains(a))
{
// Find index where A is
if (b.IndexOf(a) != -1)
{
while ((index = b.IndexOf(a, index)) != -1)
{
Console.WriteLine(A + " found at position " + index);
index++;
}
Console.ReadLine();
return b.IndexOf(a);
}
else
return -1;
}
else
{
Console.WriteLine(A + " is not in " + B + ".");
Console.ReadLine();
return -1;
}
}
else
{
Console.WriteLine(A + " must be less than " + B + ".");
// Console.ReadLine();
return -1;
}
}
else
{
Console.WriteLine("A or B is out of range.");
//Console.ReadLine();
return -1;
}
}
static void Main(string[] args)
{
int A = 53, B = 1953786;
int C = 78, D = 195378678;
int E = 57, F = 153786;
solution1(A, B);
solution1(C, D);
solution1(E, F);
Console.WriteLine();
}
보고:
위치 2에서 53 찾음
78 위치 4
에서 발견 78 위치 7에서 발견
57은 153786에 없습니다
'Program Tip' 카테고리의 다른 글
JavaScript에서 '와'의 차이점은 무엇입니까? (0) | 2020.11.10 |
---|---|
레일의 루비 레이아웃에 이미지 추가 (0) | 2020.11.10 |
jQuery : $ .ajax.error 메서드 내에서 HTTP 상태 코드를 얻는 방법은 무엇입니까? (0) | 2020.11.10 |
모든 TypeScript 소스를보고 컴파일하는 방법은 무엇입니까? (0) | 2020.11.10 |
데이터베이스에서 csv 파일로 테이블 내보내기 (0) | 2020.11.10 |