我想编写一个挤压函数squeeze(s1,s2)来删除s1中与字符串s2中的任何字符匹配的每个字符。
除了时间复杂度(m * n)之外是否还有可用的算法,即遍历字符串s1 m次(s2的长度)并跳过s2中出现的所有字符。
谢谢...
答案 0 :(得分:2)
创建一个位图(bool数组)。
遍历字符串s2,切换与字符对应的每个位。
遍历字符串s1,如果相应位为真,则跳过该字符。
如果你想允许更多的字符,显然要修改长度(下面的例子需要一个ToLower()/ ToUpper(),因为它使用26)。
粗略的C#概念证明示例(准备粘贴在LINQPad中):
void Main()
{
// Mapping the alpha lower case characters to start at zero
int magicAsciiAdjust = -96;
string s1 = "asdaswerwe"; // Assumes no non-alpha
string s2 = "asdacbBe"; // Assumes no non-alpha
string output = String.Empty;
bool[] mask = new bool[26];
foreach (char c in s2.ToLower())
{
mask[((int)c) + magicAsciiAdjust] = true;
}
foreach(char c in s1.ToLower())
{
if (!mask[((int)c) + magicAsciiAdjust])
output += c;
}
output.Dump();
}
你可以通过使你的掩码长128来支持ASCII。 (并删除ToLower()调用)等。
答案 1 :(得分:0)
使用套装
private static String squeeze(String s1, String s2) {
StringBuilder sb = new StringBuilder();
HashSet<Character> set = new HashSet<Character>();
for(char c: s2.toCharArray()) set.add(c);
for(char c: s1.toCharArray())
if(!set.contains(c))
sb.append(c);
return sb.toString();
}
使用位数组
private static String squeeze(String s1, String s2) {
StringBuilder sb = new StringBuilder();
BitSet bs = new BitSet(256);
for(char c: s2.toCharArray()) bs.set(c);
for(char c: s1.toCharArray())
if(!bs.get(c))
sb.append(c);
return sb.toString();
}
// 示例强>
String s1 = "badcode";
String s2 = "abcd";
String squeezed = squeeze(s1,s2);
输出:oe