2014-02-26 165 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找到另一個匹配相同的字符。

相關問題