2014-02-26 163 views
0

如何使用C#检查字符或数字是否仅使用一次?检查字符串是否在字符串中重复使用

有效期:

abcdef

无效:

aabbccddeeff

用法示例:

string stringToTest = "tteesstt0011"; 
if (OnlyOnceCheck(stringToTest)) 
{ 
    throw new Exception("Each character or number can be used only once"); 
} 
+5

你有没有尝试过? –

回答

10

你可以使用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()不完全一样的东西......

+0

LINQ很棒,但不恰当的用法可能很危险。 –

+0

Geez,单线产生的开销是多少? –

+0

@DavidRTribble你可以测量它。但我不会害怕这一点。虽然,我已经添加了2个更多的解决方案,没有LINQ。 – MarcinJuraszek

2

你可以使用地图(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#多。

+1

非泛型'Hashtable'?在每一次电话会议上拳击?真?我理解Java背景,但在回答C#问题时,您应该了解Java和C#之间的差异。 .NET与Java有很多不同的泛型,在这种情况下不使用它是一个巨大的错误。 – MarcinJuraszek

2

使用LINQ:

public static bool OnlyOnceCheck(string input) 
{ 
    return input.Distinct().Count() == input.Length 
} 
1

我的贡献:

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; 
} 
+0

这很聪明,但该算法的最坏情况行为是O(n^2)。但对于小字符串,它可能是最快的方式。 –

+0

当然,但它仍然比LINQ表达式快,我想.. –

+0

@AndréFigueiredo我认为这不是。 LINQ在内部使用'HashSet '作为'Distinct',其他* O(1)*查找集合用于'GroupBy',所以我期望LINQ更快。 – MarcinJuraszek

0

使用ToCharArray()方法将字符串转换成字符数组,然后遍历炭[] newStr的值,使用计数器来计算每个字符的出现次数。和If ELse语句来评估你的结果

char [] newStr = stringToTest.ToCharArray(); 
0

的更有效的方法是扫描线,逐个字符从左至右,计数的每个字符代码每次出现。一旦你击中了一个已经被计数的角色,你可以拒绝整个字符串;否则整个字符串将被扫描,并且每个字符只会出现一次。

真正的问题是确定如何跟踪字符数。如果字符串可以包含任何字符代码(全部65,536个Unicode字符),那么您最好使用整数计数的哈希表,由字符代码索引/键入。另一方面,如果您知道该字符串只包含相当小的字符子集(例如,从'\ u0000'到'\ u00FF'的ISO 8859-1 Latin-1代码),那么您可以使用一个小整数数组来保存计数器。

1

并与正则表达式:

Console.WriteLine(Regex.IsMatch("abcde", @"(.).*\1")); // False 
Console.WriteLine(Regex.IsMatch("abcce", @"(.).*\1")); // True 

(.)比赛和捕捉任何字符和\1找到另一个匹配相同的字符。

相关问题