2010-10-22 15 views
5

En C# quiero crear lógica que si una cadena como abcabda se pasa a un método, debe devolver el primer carácter no repetitivo de una cadena como en el ejemplo anterior debería devolver c. no puedo convertir una cadena en una matriz de caracteres, a continuación, cómo hacer una comparación de cada carácter de matriz con la cadena y devolver el primer carácter no repetitivo.lógica C# para obtener el primer carácter no repetitivo (distinto) de la cadena

¿Puedo hacerlo así?

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 
       } 
      } 
     } 
    } 
} 
+0

búsqueda Google con esta" El carácter duplicado en la cadena "conduce a esta página http://stackoverflow.com/questions/588774/how-to-remove-duplicate-characters-in-a-string –

+0

Si tu pregunta es" ¿Puedo hacer esto? ¿Por qué no? simplemente pruébalo tú mismo? ¿El código hace lo que se supone que debe hacer? ¿Por qué no puedes convertir una cadena en una matriz de caracteres? – HimBromBeere

Respuesta

3

Aquí está el código hasta ahora:

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 
      } 
     } 
    } 
} 

En realidad estás muy cerca. Voy a ignorar todos los problemas de estilo y las redundancias porque no son lo que estás preguntando.

Lo que realmente quieres hacer es recorrer tu cadena carácter por carácter y ver si ese carácter existe más adelante en la cadena.Si el personaje se repite, puedes dejar de buscarlo y pasar al siguiente. Si llega al final de la cadena sin encontrar una repetición, ha encontrado un carácter no duplicado y puede devolverlo. Usted tiene la mayor parte de la lógica en sus bucles x/y anidados, pero se echa en falta algunas cosas:

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: Usted ha dicho que quiere ser capaz de encontrar la longitud de la cuerda sin llamar Length, y presumiblemente sin nombrando cualquier otro método. La forma de hacerlo es usar un bucle foreach para iterar sobre los caracteres en la cadena, incrementando un contador sobre la marcha. Aquí hay un código con comentarios para que usted llene en:

// initialize counter to 0 
foreach (char ch in s) 
{ 
    // increment counter by 1 
} 
// now counter is the length of the string 
+0

esto es lo que estaba pidiendo gracias ... también quiero calcular la longitud de la cadena en lugar de usar s.length ... – NoviceToDotNet

+0

NoviceToDotNet: actualicé mi respuesta para decirle cómo calcular la longitud sin usar 's. Length' – Gabe

1

Para leer cada carácter en una cadena es tan simple como:

foreach (Char character in myString) 
{ 

} 
+0

, pero ¿cómo crear una lógica de comparación? – NoviceToDotNet

+0

No estoy escribiendo su lógica para usted, no merezco un -1 por ayudar con la sintaxis. – cjk

+0

+1 para resolver uno de los problemas del OP –

5

cómo sobre el uso de LINQ?

string test = "abcabda"; 

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

Esto devolverá 'c' según el ejemplo dado en la pregunta.

+0

No estoy seguro de que encuentre el * primer * carácter único en lugar de * algún * carácter único. –

+0

Esto devuelve "abcd" en lugar de solo c/d. –

2

"cadena" .ToCharArray() le daría una matriz que contiene los caracteres que hacen de "cadena"

2

Creo que se necesita para recorrer dos veces a través de la lista de caracteres:

  1. vez de construir una Dictionary<char, int> de carácter recuentos,
  2. y para buscar el primer carácter de la cadena cuyo recuento es igual a 1
1

una posible solución: toma cada carácter de la cadena de derecha a izquierda. para cada char, verifique cualquier otra ocurrencia del carácter en la cadena. si no hay otra ocurrencia del char en la cadena, agréguelo a una pila. una vez que haya hecho esto con todos los caracteres en la cadena, la parte superior de la pila contendrá el primer carácter no repetitivo.

+0

¿Por qué no detenerse cuando encuentre el primer personaje que satisfaga la condición? –

+0

bcos la travesía está al revés y lo que se requiere es el primer carácter no repetitivo ... espero que esté claro – Aadith

19

Parece que está buscando el primer char en la cadena con su recuento igual a 1? Versión

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

no LINQ:

for (int index = 0; index < str.Length; index++) 
    { 
     if (str.LastIndexOf(str[index]) == str.IndexOf(str[index])) 
     { 
      result = str[index]; 
      break; 
     } 
    } 
+0

no se permiten métodos de inteligencia – NoviceToDotNet

+1

@Danny Chen: Simplicidad ... – Aamir

+1

@NoviceToDotNet: Este no es un método de inteligencia. Esto es LINQ muy simple. Si está aprendiendo .NET, debe considerar aprender Linq como parte esencial de ello. Hace la vida más fácil :) – Aamir

5

Bastante simple, pero:

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

     return null; 
    } 
+0

Cambié el método porque me di cuenta de que solo revisaba hacia adelante. –

+0

Si no se permite LINQ, esta es realmente su mejor opción. ¡Solución bastante limpia! –

+0

@Jess: No es el mejor. Usando un 'for-loop' en vez de' foreach', entonces no necesita llamar 'search.IndexOf (chr)'. –

5

Se puede usar un poco de 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 
+0

no se permiten los métodos de inteligencia – NoviceToDotNet

+0

+1 para el mejor método de código asintótico y agradable. Creo que los tuyos son O (n) en promedio (hash) mientras que los otros son O (n^2). Y otra cosa, esto fracasará si no hay ninguno. Supongo que 'FirstOrDefault' sería mejor. –

2

Esto no puede ser el más eficiente, pero funciona y es fácil de leer:

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 
    } 
+0

No necesita la llamada 'ToCharArray'. Debería funcionar igual sin eso. – Gabe

+0

@Gabe - Soy de la vieja escuela. A veces tengo que atrapar mis pequeños dedos para no escribir un Enumerador. –

2

aquí es mi solución

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); 

    } 
1

Tres maneras de encontrar primer carácter que no se repite en una secuencia de C#

encontrar el código de abajo -

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; 

} 

salida increíble dos más forma -

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

0

Aquí es el O solución (n) para este problema.

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'; 
    } 
+0

Parece que esto espera que el diccionario mantenga el orden original de las claves agregado, que es [no verdadero] (https://msdn.microsoft.com/en-us/library/xfhwa508 (v = vs.110) .aspx) : 'A los fines de la enumeración, cada elemento del diccionario se trata como una estructura KeyValuePair que representa un valor y su clave. El orden en el que se devuelven los artículos no está definido. –

+0

Acepto y aquí aparece el código actualizado. –

0

Aquí es una simple lógica para conseguir primer carácter que no se repite de una cadena

Ejemplo: AABBCCdEEfGG, aquí la primera sin carbón repetir es "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(); 
     } 
    } 
} 
Cuestiones relacionadas