5

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.

CanI 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
                }
            }
        }
    }
}
Herohtar
  • 5,347
  • 4
  • 31
  • 41
NoviceToDotNet
  • 10,387
  • 36
  • 112
  • 166
  • Searching Google with this" Duplicate character in string" lead to this page http://stackoverflow.com/questions/588774/how-to-remove-duplicate-characters-in-a-string – Gopi Oct 22 '10 at 07:16
  • If your question is "can I do this", why not simply try it out yourself? Does the code do what it is supposed to do? Why are you unable to convert a string to an array of characters? – MakePeaceGreatAgain Mar 02 '18 at 09:19

16 Answers16

21

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]) == str.IndexOf(str[index]))
        {
            result = str[index];
            break;
        }
    }
Cheng Chen
  • 42,509
  • 16
  • 113
  • 174
  • 1
    @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 Oct 22 '10 at 07:25
  • @Aamir, I'm guessing this is for a class and they said 'No LINQ'. – Beep beep Oct 22 '10 at 07:27
  • @NoviceToDotNet: Note the `using` statement at the top. If you are using 2.0 or lower, try the non linq version. – Cheng Chen Oct 22 '10 at 07:30
  • Or more simply put, if you are using VisualStudio2005 or lower, use Non-Linq version. – Aamir Oct 22 '10 at 07:32
  • What is an "intelligence method"? – Gabe Oct 22 '10 at 07:34
  • @Gabe: I think he means the intelligence prompts of VS when you type a dot after some variable. – Cheng Chen Oct 22 '10 at 07:36
  • Danny Chen: You mean "Intellisense"? All methods are in Intellisense. I doubt the assignment says "You can't use methods". – Gabe Oct 22 '10 at 07:39
  • 6
    @Danny Chen: I think it means solve this without engaging brain, as he appears to be doing... – cjk Oct 22 '10 at 07:40
  • @Danny Chen: I think the non Link version might break at times. For Ex: in "teeter", lastIndex(t) and index values will become same and 't' is returned. Suggest me if I'm wrong. Thank you. – jai May 26 '11 at 07:00
  • @HanuAthena: For "teeter", `LastIndexOf('t')` is 3, and `IndexOf('t')` is 0. – Cheng Chen May 26 '11 at 11:24
  • @Danny Chen: I meant in the *non LINQ version* – jai May 26 '11 at 16:19
  • @HanuAthena: You are correct! Sorry my mistake, I've updated the answer. Great point. – Cheng Chen May 27 '11 at 01:39
7

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
  • 155,851
  • 29
  • 291
  • 343
  • +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. – Lasse Espeholt Oct 22 '10 at 07:47
5

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.
  • 46,577
  • 46
  • 119
  • 147
5

Pretty simple but:

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

        return null;
    }
Andrew Hanlon
  • 7,271
  • 4
  • 33
  • 53
4

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
    }
user268137
  • 186
  • 3
3

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
  • 38,117
  • 9
  • 79
  • 111
3

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
  • 84,912
  • 12
  • 139
  • 238
  • this is what i was asking for thanks..well i also want to calculate the length of string instead of using s.length... – NoviceToDotNet Oct 22 '10 at 08:31
  • NoviceToDotNet: I updated my answer to tell you how to calculate the length without using `s.Length` – Gabe Oct 22 '10 at 16:40
2

Here is my solution

    public static char FirstNonRepeatedChar(string input)
    {
        bool isDuplicate;
        for (int i = 0; i < input.Length; i++)
        {
             isDuplicate = false;

            for (int j = 0; j < input.Length; j++)
            {
                if ((input[i] == input[j]) && i !=j )
                {
                    isDuplicate = true;
                    break;
                }

            }
            if (!isDuplicate)
            {
                return input[i];
            }

        }
        return default(char);

    }
vikram
  • 21
  • 2
2

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

Aadith Ramia
  • 10,005
  • 19
  • 67
  • 86
1

Three ways to find first non repeating character in a string c#

find the code below -

public char firstNonRepetitive(string inputString)
{
 int nextOccurrence = 0;
 char firstDistinctChar = ' ';
 for (int i = 0; i < inputString.Length; i++)
 {
    nextOccurrence = 0;
    for (int j = (i + 1); j < inputString.Length; j++)
    {
        if (inputString[i] == inputString[j])
            nextOccurrence++;
    }
    if (nextOccurrence == 0)
    {
        firstDistinctChar = inputString[i];
        break;
    }
  }
  return firstDistinctChar;

}

Check out amazing two more way -

program to find first non repeating character in a string c# - three ways

Rohit
  • 1,653
  • 1
  • 13
  • 5
1

Here is the O(n) solution for this problem.

public static char FirstNonRepeatedChar(string inputString)
    {
        if (String.IsNullOrEmpty(inputString))
            return '\0';
        if (inputString.Length == 1)
            return inputString[0];

        Hashtable charTable = new Hashtable();
        for (int i = 0; i <= (inputString.Length - 1); i++)
        {
            if (charTable.Contains(inputString[i]))
            {
                int currentCount = Int16.Parse(charTable[inputString[i]].ToString());
                charTable[inputString[i]] = currentCount + 1;
            }
            else
                charTable.Add(inputString[i], 1);
        }
        for (int i = 0; i <= (inputString.Length - 1); i++)
        {
            if (charTable[inputString[i]].ToString() == "1")
            {
                return char.Parse(inputString[i].ToString());
            }
        }
        return '\0';
    }
  • Looks like this expects dictionary to keep original order of keys added, which is [not true](https://msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx): `For purposes of enumeration, each item in the dictionary is treated as a KeyValuePair structure representing a value and its key. The order in which the items are returned is undefined.` – Alexandr Sugak Sep 23 '16 at 11:16
1

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

foreach (Char character in myString)
{

}
cjk
  • 45,739
  • 9
  • 81
  • 112
1

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 Ramia
  • 10,005
  • 19
  • 67
  • 86
0

Here is a simple logic to get first non repeating character from a string

Example : AABBCCdEEfGG , here the first no repeating char is "d"

namespace PurushLogics
{
    class Purush_FirstNonRepeatingChar
    {
        public static void Main()
        {
            string inputString = "AABBCCdEEfGG";
            int i = 0;
            char[] a = inputString.ToCharArray();
            bool repeat = false;
            for (i = 0; i < a.Length; )
            {

                for (int j = i + 1; j < a.Length; )
                {
                    if (a[i] == a[j])
                    {
                        a = a.Where(w => w != a[i]).ToArray(); // Will return the array removing/deleting the character that is in a[i] location
                        repeat = true;
                        break;
                    }
                    else
                    {

                        repeat = false;
                    }

                    break;
                }

                if (repeat == false || a.Length == 1)
                {
                    break;
                }
            }
            Console.WriteLine(a[i]);
            Console.ReadKey();
        }
    }
}
Purushoth
  • 59
  • 4
0

Time Complexity O(n) solution :

public static char GetNonRepeatingFirstCharacter(string str)
    {
        char firstNonRepeatingChar = default(char);
        if(!string.IsNullOrWhiteSpace(str))
        {
            // as we are dealing with lowercase letter and array index is starting from ZERO
            // we are taking the ASCII value of character 'a' which is 97 
            // so that we can assign if the character is 'a' we can assign to the index zero of array.
            int asciiOfInitialChar = 'a';

            // array index 26 as we have only 26 alphabet. 
            int[] alphabetArray = new int[26];

            // loop through the string provided. 
            // O(n) as it loops till the length of the array.
            foreach (var ch in str)
            {
                // checking if the array contains only lowercase character else throw format exception.
                if (ch < 97 || ch > 122)
                {
                    throw new FormatException("Given string contain non lowercase alphabet");
                }

                // subtracting with 97 so we can assign 'a' to index 0 and b to index 1 so on..
                var index = ch - asciiOfInitialChar;
                // incrementing the count so that we can get to know how many character is there in a string
                alphabetArray[ch - asciiOfInitialChar]++;
            }

            // fixed looping, can be considered as O(1) as it is always loop 26 times irrespective of length of the array
            for (int i = 0; i < 26; i++)
            {
                //finding first non repeating character as we have count of the characters in the alphabetArray
                if (alphabetArray[i] == 1)
                {
                    // converting to character by adding the asciiOfinitialChar 97 
                    // so that we will get if the index is 1 then 1 + 97 = 98  which is the ASCII vale of character 'b'
                    // break the loop as we found first non repeating character
                    firstNonRepeatingChar = (char)(i + asciiOfInitialChar);
                    break;
                }
            }


        }

        return firstNonRepeatingChar;
    }

Solution with unit test case:

GitHub: solution with unit test

ghosh-arun
  • 51
  • 4
0

The logic will give you the first non repetitive character of string, if you want to get the index of that char from string just replace 'a.indexOf(x)'with 'x' in Sysop.

package practice.learning;

import java.util.Scanner; public class FirstRepetitiveTwo {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Scanner sc=new Scanner(System.in);
    
    String a=sc.nextLine();
    int count=0;
    char x=' ';
    for(int i=0;i<=a.length()-1;i++) {
        x=a.charAt(i);
        for(int j=0;j<=a.length()-1;j++) {
            if(x==a.charAt(j)) {
                count++;
                }
        }
        if(count==1) {
            break;
        }
        count=0;
    }
    System.out.println(x);  
}

} enter image description here

Pawan
  • 14
  • 2