Reputation: 1287
How can I check if character or number is used only once using C#?
Valid:
abcdef
Invalid:
aabbccddeeff
Example usage:
string stringToTest = "tteesstt0011";
if (OnlyOnceCheck(stringToTest))
{
throw new Exception("Each character or number can be used only once");
}
Upvotes: 1
Views: 13478
Reputation: 305
Linq Query to find if any char has a duplicate:
var Duplicates = str.GroupBy(x => x).ToDictionary(x => x.Key, y => y.Count()).Any(x => x.Value > 1);
Upvotes: 0
Reputation: 1633
You could use a map (hashmap for example) with characters as keys and their occurrence as value. If any value is > 1 then the string is invalid. Or simply while adding the key to map, if it already exists, the string is invalid.
in 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;
}
Sorry for my java like coding style, I have not used C# much.
Upvotes: 2
Reputation: 125630
You could use LINQ:
public static bool OnlyOnceCheck(string input)
{
return input.GroupBy(x => x).Any(g => g.Count() > 1);
}
or with Distinct
:
public static bool OnlyOnceCheck(string input)
{
return input.Distinct().Count() == input.Length;
}
Update
If someone is afraid about performance, you can always get a little better with HasSet<char>
:
public static bool OnlyOnceCheck(string input)
{
var set = new HashSet<char>();
return input.Any(x => !set.Add(x));
}
or if you're afraid about delegate invocation overhead you can use for
loop:
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;
}
but Any()
on string
does exactly the same thing...
Upvotes: 18
Reputation: 11788
And with a regex:
Console.WriteLine(Regex.IsMatch("abcde", @"(.).*\1")); // False
Console.WriteLine(Regex.IsMatch("abcce", @"(.).*\1")); // True
(.)
matches and captures any character and \1
finds another match for the same character.
Upvotes: 1
Reputation: 12204
The more efficient method is to scan the string, character by character from left to right, counting each occurrence of each character code. Once you hit a character that has already been counted, you can reject the whole string; otherwise the whole string gets scanned and each character in it only occurs once.
The real problem is determining how you are going to keep track of the character counts. If the string can contain any character codes (all 65,536 Unicode characters), then you are best off using a hash table of integer counts, indexed/keyed by character codes.
On the other hand, if you know that the string will only contain a fairly small subset of characters (say, the ISO 8859-1 Latin-1 codes from '\u0000' to '\u00FF'), then you can use a small integer array to hold the counters.
Upvotes: 0
Reputation: 7679
Use the ToCharArray()
method to convert your string into an Array of Characters and then loop through the values of the char [] newStr
, using a counter to count occurrences of each Char . and If ELse
statement to evaluate your result
char [] newStr = stringToTest.ToCharArray();
Upvotes: 0
Reputation: 13425
My contribution:
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;
}
Upvotes: 1
Reputation: 62472
Using Linq:
public static bool OnlyOnceCheck(string input)
{
return input.Distinct().Count() == input.Length
}
Upvotes: 2