首先,我知道如果string
包含Ascii table
,如何找到第一个不重复的字符,例如:`" abccba .."
问题或问题是:如何找到string/buffer
中的第一个非重复字符包含混合字母?我的意思是我们不知道语言是什么!
也许是英语或阿拉伯语或两种语言之间的混合,我必须在 O(n)中这样做
HashMap
,那么get
和put
费用为O(1)
[PROVE]?string
还是其他容器?答案 0 :(得分:0)
制作一张计算出现次数的<Character, Integer>
地图,一次逐个字符地查看整个字符串,如果它不存在(数量为1),则将其添加到地图中,或者增加发生的次数,如果已经存在的话。然后再次遍历整个String,并返回您找到的第一个有计数的项目。此处不需要计算出现次数,可以用不同的方式完成,也可以在2处停止,但如果你正在尝试,它可能会很有用稍后扩展您的代码以执行更多操作。当然,如果你使用阿拉伯语字母,你需要处理潜在的unicode问题,但我认为这不是你所问的问题。这个解决方案是O(N),你要经历你的String 2次,并且地图操作更便宜。
答案 1 :(得分:0)
如果HashMap
解决方案不够好,我可以想到:创建java.util.BitSet
,seenOnce
和seenTwice
的两个实例,每个实例都有0x10000位。对于每个字符,如果它已在seenOnce
中,请将其添加到seenTwice
,否则将其添加到seenOnce
。第二次打败字符串,打印出不在seenTwice
中的第一个字符。
答案 2 :(得分:0)
在 C#... 中,O(n)时间复杂度...
public char GetFirstRecuringChar(string text)
{
if (string.IsNullOrEmpty(text) || string.IsNullOrWhiteSpace(text))
{
throw new ArgumentNullException();
}
IDictionary<char, CharIndex> map = new Dictionary<char, CharIndex>();
for (int i = 0; i < text.Length; i++)
{
if (map.ContainsKey(text[i]))
{
map[text[i]].Count++;
}
else
{
CharIndex ci = new CharIndex { Index = i, Ch = text[i], Count = 1 };
map.Add(text[i], ci);
}
}
int lowestIndex = int.MaxValue;
foreach (CharIndex charIndex in map.Values)
{
if (charIndex.Count == 1)
{
if (lowestIndex > charIndex.Index)
{
lowestIndex = charIndex.Index;
}
}
}
char answer = '\n';
if (lowestIndex != int.MaxValue)
{
foreach (CharIndex charIndex in map.Values)
{
if (charIndex.Index == lowestIndex)
{
answer = charIndex.Ch;
break;
}
}
}
return answer;
}
private class CharIndex
{
public char Ch { get; set; }
public int Index { get; set; }
public int Count { get; set; }
}
单元测试:
[TestCase("ississippitotalm", 'o')]
[TestCase("a", 'a')]
[TestCase("teeter", 'r')]
[TestCase("teeterxyz", 'r')]
[TestCase(".......................................x.................f.........y...xkiuytreeee", 'f')]
public void GetFirstRecuringCharTest(string text, char expectedAnswer)
{
char result = runner.GetFirstRecuringChar(text);
Assert.That(result, Is.EqualTo(expectedAnswer));
}