이 특히 효율적 아니지만, 아마 짧은 문자열을 충분히 빨리 될 것입니다 :
string s1 = "move";
string s2 = "remove";
foreach (char charToRemove in s1)
{
int index = s2.IndexOf(charToRemove);
if (index >= 0)
s2 = s2.Remove(index, 1);
}
// Result is now in s2.
Console.WriteLine(s2);
이 피하는로 변환 char 배열.
그러나 강조하기 위해 : 이것은 큰 문자열의 경우 매우 느립니다.
[편집]
나는 몇 가지 테스트를 수행 한하고이 코드가 꽤 빨리 사실에 있음을 밝혀졌습니다.
여기 코드를 다른 답변의 최적화 된 코드와 비교합니다. 그러나 여기에서는 코드가 OP의 요구 사항을 올바르게 구현하고 있으므로 다른 코드는 올바르게 구현하지 않기 때문에 전체적으로 공정하게 비교하지는 않습니다. 그러나 HashSet을 사용하면 생각만큼 도움이되지 않는다는 것을 보여줍니다.
디버거에서 실행하지 않고 릴리스 빌드에서이 코드를 테스트했습니다 (디버거에서 실행하는 경우 디버그 빌드는 잘못된 타이밍을 제공하는 릴리스 빌드가 아닙니다).
이 테스트에서는 길이가 1024 인 대상 문자열을 사용하고 제거 할 문자는 == "SKFPBPENAALDKOWJKFPOSKLW"
입니다.
test1() took 00:00:00.2891665
test2() took 00:00:00.1004743
test1() took 00:00:00.2720192
test2() took 00:00:00.0993898
test1() took 00:00:00.2753971
test2() took 00:00:00.0997268
test1() took 00:00:00.2754325
test2() took 00:00:00.1026486
test1() took 00:00:00.2785548
test2() took 00:00:00.1039417
test1() took 00:00:00.2818029
test2() took 00:00:00.1029695
test1() took 00:00:00.2727377
test2() took 00:00:00.0995654
test1() took 00:00:00.2711982
test2() took 00:00:00.1009849
당신이 볼 수 있듯이이 test2()
일관 test1()
을 능가하는 성능 : test1()
는 다른 답변에서 잘못된하지만 가정으로 최적화 된 솔루션이다
내 결과 및 test2()
내 최적화되지 않은 있지만 올바른 솔루션입니다. 문자열의 길이가 증가하는 경우에도 마찬가지 남아 8192
테스트 코드 :
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace Demo
{
public static class Program
{
private static void Main(string[] args)
{
var sw = new Stopwatch();
string text = randomString(8192, 27367);
string charsToRemove = "SKFPBPENAALDKOWJKFPOSKLW";
int dummyLength = 0;
int iters = 10000;
for (int trial = 0; trial < 8; ++trial)
{
sw.Restart();
for (int i = 0; i < iters; ++i)
dummyLength += test1(text, charsToRemove).Length;
Console.WriteLine("test1() took " + sw.Elapsed);
sw.Restart();
for (int i = 0; i < iters; ++i)
dummyLength += test2(text, charsToRemove).Length;
Console.WriteLine("test2() took " + sw.Elapsed);
Console.WriteLine();
}
}
private static string randomString(int length, int seed)
{
var rng = new Random(seed);
var sb = new StringBuilder(length);
for (int i = 0; i < length; ++i)
sb.Append((char) rng.Next(65, 65 + 26*2));
return sb.ToString();
}
private static string test1(string text, string charsToRemove)
{
HashSet<char> excludeCharacters = new HashSet<char>(charsToRemove);
StringBuilder sb = new StringBuilder();
foreach (char ch in text)
{
if (!excludeCharacters.Contains(ch))
{
sb.Append(ch);
}
}
return sb.ToString();
}
private static string test2(string text, string charsToRemove)
{
foreach (char charToRemove in charsToRemove)
{
int index = text.IndexOf(charToRemove);
if (index >= 0)
text = text.Remove(index, 1);
}
return text;
}
}
}
[수정 2]
여기에 훨씬 더 최적화 된 솔루션입니다 :
public static string RemoveChars(string text, string charsToRemove)
{
char[] result = new char[text.Length];
char[] targets = charsToRemove.ToCharArray();
int n = 0;
int m = targets.Length;
foreach (char ch in text)
{
if (m == 0)
{
result[n++] = ch;
}
else
{
int index = findFirst(targets, ch, m);
if (index < 0)
{
result[n++] = ch;
}
else
{
if (m > 1)
{
--m;
targets[index] = targets[m];
}
else
{
m = 0;
}
}
}
}
return new string(result, 0, n);
}
private static int findFirst(char[] chars, char target, int n)
{
for (int i = 0; i < n; ++i)
if (chars[i] == target)
return i;
return -1;
}
가 위의 테스트 프로그램에이를 연결하면 test2()
보다 3 배 빠른 속도로 실행됩니다.
단순히 '문자열'을 사용하지 않는 이유는 무엇입니까? –
아마도'var c3 = s2.Replace (s1, "") .ToCharArray();'를 원하지만'm','o','v' 및'e'를'remove'에서 제거하면 남게됩니다. 'r'을 사용하면'e'를 모두 제거 할 수 있기 때문입니다. 아마 당신이 궁극적으로하고 싶은 것을 설명해야합니다. –
예, 명확히하십시오. 단순히 하위 문자열을 제거 하시겠습니까? 아니면 remove 배열의 모든 문자를 제거 하시겠습니까? 아니면 move 배열의 각 문자가 처음 나오는 것을 제거하고 있습니까? –