tags:

views:

161

answers:

10

In c# i want to create logic that if i a string like abcabda is passed to a method then it should return first non repeative character from string like in above it should return c. i am unable to convert a string to array of character then how to make comparison of each array character to the string and return the first non repeative character.

please provide me some logic

can i make it like this

class A
{
    static void main()
    {
        A a=new A();
        char  ch=a.m1(abcabd);
    }
}

class B
{
    char m1(string s)
    {
        string s1=s;
        char[] ch1=new char[s.length];
        for(int x=0; x<s.length;x++)
        {
            ch1[x]=s[x];
        }
        for(int x=0; x<s.length; x++)
        {
            for(int y=0; y<s.lenth; y++)
            {
                if(s[x]=ch1[y])
                {             
/// here i am confused how to create logic for comparison please let me know
// and how to return the character
                }
            }
        }
    }
}
A: 

To read each character in a string is as simple as:

foreach (Char character in myString)
{

}
ck
but how to create comparison logic?
NoviceToDotNet
I'm not writing your logic for you, don't deserve a -1 for helping with the syntax.
ck
+1 for solving one of the OP's issues
Matt Ellen
+3  A: 

how about using LINQ?

string test = "abcabda";

var selectedChars = (from c in test.ToCharArray() 
                    group c by c into groups
                    where groups.Count() == 1
                    select groups).First();

This will return 'c' as per the example given in the question.

TK
I'm not sure that you then find the *first* unique character as opposed to *some* unique character.
Hans Kesting
This returns "abcd" instead of just c / d.
Shaharyar
+2  A: 

"string".ToCharArray() would give you an array containing characters that make "string"

Aadith
+2  A: 

I think you need to loop twice through the list of characters:

  1. Once to build a Dictionary<char, int> of character-counts,
  2. Then to find the first character in the string whose count equals 1
Hans Kesting
+1  A: 

one possible solution: take each character from the string from right to left. for each char, check for any other occurence of the character in the string. if there is no other occurence of the char in the string, add it to a stack. once you have done this to all the chars in the string, the top of the stack would contain the first non-repetitive character.

Aadith
Why not just stop when you find the first character that satisfies the condition?
Kirk Broadhurst
bcos the traversal is backwards and what is required is the first non-repetitive character..hope i'm clear
Aadith
+12  A: 

It seems that you are looking for the first char in the string with its count equals to 1?

using System.Linq;
string str = "abcabda";
char result = str.FirstOrDefault(ch => str.IndexOf(ch) == str.LastIndexOf(ch));

Non LINQ version:

    for (int index = 0; index < str.Length; index++)
    {
        if (str.LastIndexOf(str[index]) == index)
        {
            result = str[index];
            break;
        }
    }
Danny Chen
no intelligence methods are allowed
NoviceToDotNet
@Danny Chen: Simplicity...
Aamir
@NoviceToDotNet: This is not an intelligence method. This is very simple LINQ. If you are learning .NET, you should consider learning Linq as an essential part of it. It makes life easy :)
Aamir
@Aamir, I'm guessing this is for a class and they said 'No LINQ'.
Jess
@NoviceToDotNet: Note the `using` statement at the top. If you are using 2.0 or lower, try the non linq version.
Danny Chen
Or more simply put, if you are using VisualStudio2005 or lower, use Non-Linq version.
Aamir
What is an "intelligence method"?
Gabe
@Gabe: I think he means the intelligence prompts of VS when you type a dot after some variable.
Danny Chen
Danny Chen: You mean "Intellisense"? All methods are in Intellisense. I doubt the assignment says "You can't use methods".
Gabe
@Danny Chen: I think it means solve this without engaging brain, as he appears to be doing...
ck
+3  A: 

Pretty simple but:

    private char? findNonRepeat(string search)
    {
        foreach(char chr in search)
        {
            if (search.LastIndexOf(chr) == search.IndexOf(chr))
                return chr;
        }

        return null;
    }
ach
I changed the method since I realised it only checked forwards.
ach
If no LINQ is allowed, this is really your best bet. Pretty neat solution!
Jess
@Jess: Not the best one. Using a `for-loop` instead of `foreach`, then you don't need to call `search.IndexOf(chr)`.
Danny Chen
@Danny - I just meant the best of the bunch here ... not necessarily the most efficient/best in general.
Jess
+5  A: 

You could use a bit of LINQ:

char result = input
    .GroupBy(c => c)             // group the characters
    .Where(g => g.Count() == 1)  // filter out groups with only 1 occurence
    .Select(g => g.Key)          // get the character from each remaining group
    .First();                    // return the first one
Fredrik Mörk
no intelligence methods are allowed
NoviceToDotNet
+1 for the best method asymptotically and nice code. I would think yours are O(n) on average (hashing) while the others are O(n^2). And another thing, this will fail if there is none. I guess `FirstOrDefault` would be better.
lasseespeholt
+2  A: 

This may not be the most efficient, but it works and is easy to read:

    public string FirstNonRepeatingChar(string inString)
    {
        var array = inString.ToCharArray();
        foreach (char distinctChar in array.Distinct())
        {
            if (array.Count(x => x == distinctChar) == 1)
                return distinctChar.ToString();
        }
        return null; //none
    }
You don't need the `ToCharArray` call. It should work just the same without it.
Gabe
@Gabe - I'm old school. Sometimes I have to catch my tiny fingers from typing an Enumerator.
Jess
+2  A: 

Here's your code so far:

char m1(string s) 
{ 
    string s1=s; 
    char[] ch1=new char[s.length]; 
    for(int x=0; x<s.length;x++) 
    { 
        ch1[x]=s[x]; 
    } 
    for(int x=0; x<s.length; x++) 
    { 
        for(int y=0; y<s.lenth; y++) 
        { 
            if(s[x]=ch1[y]) 
            {              
/// here i am confused how to create logic for comparison please let me know 
// and how to return the character 
            } 
        } 
    } 
} 

You're actually pretty close. I'm going to ignore all the stylistic problems and redundancies because they're not what you're asking about.

What you really want to do is step through your string character-by-character and see if that character exists later on in the string. If the character repeats, you can stop looking for it and go on to the next one. If you get to the end of the string without finding a repeat, you have found a non-duplicate character and can return it. You have most of the logic in your nested x/y loops, but are missing a few things:

    for(int x=0; x<s.length; x++) 
    {
        // you need a flag here to indicate whether your character is a duplicate
        for(int y=0; y<s.lenth; y++) // this loop should start at x+1, not 0
        { 
            if(s[x]=ch1[y]) // you need == instead of =
            {              
                // if you've gotten here, you have a duplicate --
                // set your flag to true and break out of the loop
            }
        }
        // at this point you should check your flag and
        // if it's not set, return your character: s[x]
    }

EDIT: You mentioned that you want to be able to find the string's length without calling Length, and presumably without naming any other methods. The way to do this is to use a foreach loop to iterate over the characters in the string, incrementing a counter as you go. Here is some code with comments for you to fill in:

// initialize counter to 0
foreach (char ch in s)
{
    // increment counter by 1
}
// now counter is the length of the string
Gabe
this is what i was asking for thanks..well i also want to calculate the length of string instead of using s.length...
NoviceToDotNet
NoviceToDotNet: I updated my answer to tell you how to calculate the length without using `s.Length`
Gabe