如何使用C#检查字符或数字是否仅使用一次?检查字符串是否在字符串中重复使用
有效期:
abcdef
无效:
aabbccddeeff
用法示例:
string stringToTest = "tteesstt0011";
if (OnlyOnceCheck(stringToTest))
{
throw new Exception("Each character or number can be used only once");
}
如何使用C#检查字符或数字是否仅使用一次?检查字符串是否在字符串中重复使用
有效期:
abcdef
无效:
aabbccddeeff
用法示例:
string stringToTest = "tteesstt0011";
if (OnlyOnceCheck(stringToTest))
{
throw new Exception("Each character or number can be used only once");
}
你可以使用LINQ:
public static bool OnlyOnceCheck(string input)
{
return input.GroupBy(x => x).Any(g => g.Count() > 1);
}
或Distinct
:
public static bool OnlyOnceCheck(string input)
{
return input.Distinct().Count() == input.Length;
}
更新
如果有人担心有关性能,你总是可以得到与HasSet<char>
好一点:
public static bool OnlyOnceCheck(string input)
{
var set = new HashSet<char>();
return input.Any(x => !set.Add(x));
}
,或者如果您'担心委托调用开销可以使用for
循环:在string
public static bool OnlyOnceCheck(string input)
{
var set = new HashSet<char>();
for (int i = 0; i < input.Length; i++)
if (!set.Add(input[i]))
return false;
return true;
}
但Any()
不完全一样的东西......
LINQ很棒,但不恰当的用法可能很危险。 –
Geez,单线产生的开销是多少? –
@DavidRTribble你可以测量它。但我不会害怕这一点。虽然,我已经添加了2个更多的解决方案,没有LINQ。 – MarcinJuraszek
你可以使用地图(HashMap中为例)与字符键和作为价值发生。如果任何值大于1,则该字符串无效。 或者只是在添加映射键时,如果它已经存在,则该字符串无效。
在C#:
static bool OnlyOnceCheck(String str){
Hashtable myHT = new Hashtable();
for (int i=0; i<str.Length; i++){
if (!myHT.ContainsKey(str[i])){
myHT.Add(str[i],1);
} else return true;
}
return false;
}
对不起,我喜欢的java编码风格,我没有使用C#多。
非泛型'Hashtable'?在每一次电话会议上拳击?真?我理解Java背景,但在回答C#问题时,您应该了解Java和C#之间的差异。 .NET与Java有很多不同的泛型,在这种情况下不使用它是一个巨大的错误。 – MarcinJuraszek
使用LINQ:
public static bool OnlyOnceCheck(string input)
{
return input.Distinct().Count() == input.Length
}
我的贡献:
private bool OnlyOnceCheck(string value){
if (value == null)
return true;
for(int i = 0; i < value.length; i++){
if (value.LastIndexOf(value[i]) != i){
return false;
}
}
return true;
}
这很聪明,但该算法的最坏情况行为是O(n^2)。但对于小字符串,它可能是最快的方式。 –
当然,但它仍然比LINQ表达式快,我想.. –
@AndréFigueiredo我认为这不是。 LINQ在内部使用'HashSet
使用ToCharArray()
方法将字符串转换成字符数组,然后遍历炭[] newStr
的值,使用计数器来计算每个字符的出现次数。和If ELse
语句来评估你的结果
char [] newStr = stringToTest.ToCharArray();
的更有效的方法是扫描线,逐个字符从左至右,计数的每个字符代码每次出现。一旦你击中了一个已经被计数的角色,你可以拒绝整个字符串;否则整个字符串将被扫描,并且每个字符只会出现一次。
真正的问题是确定如何跟踪字符数。如果字符串可以包含任何字符代码(全部65,536个Unicode字符),那么您最好使用整数计数的哈希表,由字符代码索引/键入。另一方面,如果您知道该字符串只包含相当小的字符子集(例如,从'\ u0000'到'\ u00FF'的ISO 8859-1 Latin-1代码),那么您可以使用一个小整数数组来保存计数器。
并与正则表达式:
Console.WriteLine(Regex.IsMatch("abcde", @"(.).*\1")); // False
Console.WriteLine(Regex.IsMatch("abcce", @"(.).*\1")); // True
(.)
比赛和捕捉任何字符和\1
找到另一个匹配相同的字符。
你有没有尝试过? –