我试图解决这个问题。
基本上我需要从字符数组中选择第二个副本。
Input {'x','y','z','x','y'} output: y
Input { 'a', 'a', 'b', 'a', 'c', 'b', 'a', 'c', 'b' } Output: b
Input { 'a','a','a','b','a','c','b','a','c','b' } output: b
编辑:
Input {'a', 'b', 'c', 'b', 'a', 'c', 'b', 'a', 'c', 'b'} Output: a
我尝试过编写这段代码,但如果第一个字符立即重复,它会失败:(有任何帮助纠正这个问题吗?
public static char returnSecondDuplicate(char[] arr)
{
if (arr.Length == 0)
throw new ArgumentNullException("empty input");
var dictionary = new Dictionary<char, int>();
Char second = '\0';
int duplicateCount = 0;
for (int i = 0; i <= arr.Length - 1; i++)
{
if (!dictionary.ContainsKey(arr[i]))
{
dictionary.Add(arr[i], 1);
}
else
{
duplicateCount++;
if (duplicateCount == 2)
{
second = arr[i];
}
}
}
return second;
}
答案 0 :(得分:2)
这应该很好地解决它:
var secondDuplicate = input.GroupBy( c => c)
.Where( g => g.Count() > 1)
.Skip(1)
.First()
.Key;
首先你将它们分组,然后用只有一个元素折扣所有组(因为它们不是重复的),然后取第二个(通过跳过第一个)
答案 1 :(得分:2)
这是适用于特定情况的通用扩展方法:
public static T GetNthDuplicate<T>(this IEnumerable<T> source, int n)
{
HashSet<T> hashSet = new HashSet<T>();
return source.Where(item => !hashSet.Add(item))
.Distinct().Skip(n - 1) //one based index
.FirstOrDefault();
}
答案 2 :(得分:1)
问题是你在计算重复的总数,而不是单个字符的重复数。
已经介绍了一些linq答案,但如果您想知道如何修复现有代码,可以执行以下操作:
public static char returnSecondDuplicate(char[] arr)
{
if (arr.Length == 0)
throw new ArgumentNullException("Empty Array passed");
var dictionary = new Dictionary<char, int>();
char firstDuplicate = '\0';
for (int i = 0; i <= arr.Length - 1; i++)
{
if (!dictionary.ContainsKey(arr[i]))
{
dictionary.Add(arr[i], 1);
}
else if (firstDuplicate == '\0')
{
firstDuplicate = arr[i];
}
else if(arr[i] != firstDuplicate)
{
return arr[i];
}
}
return '\0'; //not found
}
基本上,您必须先跟踪哪个字母重复。一旦你有第一个副本,检查后续的不是相同的字母。不同的第一个副本是您想要返回的内容。
答案 3 :(得分:1)
原始代码的问题是,当您看到重复的字符时,每增加时间,但是,您没有检测到它是否已被考虑在内。一个简单的改变是使用一个列表(而不是一个整数)来跟踪重复项。
另外,另一个小的增强(在我看来)是使用while
循环而不是for
,因为你只想迭代直到满足某些条件,所以它似乎更合适,例如
public static char returnSecondDuplicate(char[] arr)
{
if (arr.Length == 0)
throw new ArgumentNullException("Empty Array passed");
var dictionary = new Dictionary<char, int>();
var duplicates = new List<char>();
Char second = '\0';
int i = 0;
while (duplicates.Count != 2 && dictionary.Count != arr.Length)
{
if (!dictionary.ContainsKey(arr[i]))
dictionary.Add(arr[i], 1);
else if (!duplicates.Contains(arr[i]))
duplicates.Add(arr[i]); // only add duplicates once (ignoring any duplicate duplicates!)
second = duplicates.Count == 2 ? arr[i] : second;
i++;
}
return second;
}