PSSGCSim
PSSGCSim

Reputation: 1287

Check if characters are duplicated in a string

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

Answers (8)

Nasser X
Nasser X

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

Wajahat
Wajahat

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

MarcinJuraszek
MarcinJuraszek

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

heijp06
heijp06

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

David R Tribble
David R Tribble

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

z atef
z atef

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

Andre Figueiredo
Andre Figueiredo

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

Sean
Sean

Reputation: 62472

Using Linq:

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

Upvotes: 2

Related Questions