3
votes

Comment diviser une chaîne de nombres sur le caractère d'espace blanc et convertir en nombres entiers

Je travaille sur quelques devoirs et je dois obtenir une entrée de l'utilisateur qui est une seule ligne de nombres séparés par des espaces. Je veux diviser cette chaîne et obtenir les nombres individuels afin de pouvoir les insérer dans un arbre de recherche binaire.

J'ai essayé la fonction de fractionnement et j'ai pu me débarrasser de l'espace blanc, mais je ne sais pas comment "collecter" les nombres individuels.

        string data;
        string[] newdata = { };
        Console.WriteLine("Please enter a list of integers with spaces 
                           between each number.\n");
        data = Console.ReadLine();
        newdata = data.Split(null);

        Console.WriteLine(String.Join(Environment.NewLine, newdata));

Je veux collectez les éléments du tableau de chaînes newdata et convertissez-les en entiers, mais j'ai du mal à trouver comment faire cela.

c#

1 commentaires

Vous avez déjà trouvé en utilisant Split (data.Split ()) pour obtenir un tableau de chaînes. Ensuite, utilisez int.TryParse pour essayer de convertir chaque membre du tableau en un entier. Jetez ceux que vous ne pouvez pas analyser.


5 Réponses :


0
votes

Gardez les espaces et faites le "split" en utilisant l'espace "data.split ('');".


0 commentaires

1
votes

Vous pouvez faire comme suit.

var listOfNumbers = numbers.Split(new[]{" "},StringSplitOptions.RemoveEmptyEntries)
                   .Select(x=> 
                    {
                        Console.WriteLine(x);
                        if(Int32.TryParse(x,out var number))
                            return number;
                        else
                            throw new Exception("Element is not a number");
                    });

Les lignes ci-dessus divisent l'entrée utilisateur en fonction des "espaces", supprimant toutes les entrées vides entre les deux, puis convertissent les numéros de chaîne en nombres entiers.

/ p>

Le StringSplitOptions.RemoveEmptyEntries garantit que les entrées vides sont supprimées. Un exemple d'entrée vide serait une chaîne dans laquelle deux délimiteurs se trouvent l'un à côté de l'autre. Par exemple, "2 3 4 5" , il y a deux espaces entre 2 et 3, ce qui signifie que lorsque vous divisez la chaîne avec des espaces comme délimiteur, vous vous retrouvez avec un élément vide dans le tableau. Ceci est éliminé par l'utilisation de StringSplitOptions.RemoveEmptyEntries

Selon que vous attendez des entiers ou des décimales, vous pouvez utiliser Int32.Parse ou Double.Parse (ou float / decimal etc)

De plus, vous pouvez inclure des vérifications pour vous assurer que vous avez un nombre valide, sinon lancer une exception. Vous pouvez modifier la requête comme suit.

var numbers = Console.ReadLine();
var listOfNumbers = numbers.Split(new[]{" "},StringSplitOptions.RemoveEmptyEntries)
                           .Select(x=> Int32.Parse(x));

Cela garantit que tous les éléments de la liste sont des nombres valides, sinon lèvera une exception.


0 commentaires

5
votes

Eh bien, vous pouvez utiliser la méthode Linq .Select combinée avec la méthode .Split :

List<int> newData = data.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries)
                        .Select(s => int.TryParse(s.Trim(), out var n) ? (int?)n : null)
                        .Where(x => x != null)
                        .Select(i => i.Value)
                        .ToList();

Si vous voulez que l'utilisateur puisse pour entrer des espaces vides, nous devons couper les chaînes résultantes après la séparation. Pour cela, nous pouvons utiliser une autre surcharge de la méthode string.Split qui accepte StringSplitOptions :

List<int> newData = data.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();

Enfin si vous voulez permettre à l'utilisateur de saisir parfois des données incorrectes tout en continuant d'obtenir une collection d'entiers valides que vous pourriez utiliser int.TryParse et de filtrer les valeurs qui n'ont pas été correctement analysées:

List<int> newData = data.Split(' ').Select(int.Parse).ToList();


6 commentaires

Et si l'utilisateur a saisi 1 23 42 Banana 45 ?


Il est déjà couvert par la méthode TryParse qui sélectionnera null si false et plus tard où condition.


@LukaszBalazy, il a ensuite été modifié pour utiliser TryParse. FWIW, cela devrait être TryParse depuis le début, et le rognage est une étape inutile.


@CetinBasoz Eh bien, ça ne devrait pas. L'OP n'a pas précisé qu'il attendait des entrées invalides ... Il voulait juste obtenir des nombres à partir de la chaîne


Avez-vous vraiment besoin d'OP pour spécifier que lorsque OP dit que l'entrée est avec ReadLine. C'est à quoi il faut s'attendre naturellement, non?


@CetinBasoz Cela dépend du scénario spécifique avec lequel l'OP travaille. Parfois, un comportement attendu pour une telle application serait de lever une exception pour une entrée non valide ... Mais j'utiliserais tryparse dans la plupart des cas bien sûr



3
votes

OK comme code:

var words = data.Split();
int i;
List<int> integers = new List<int>();
foreach(var s in words)
{
  if (int.TryParse(s, out i)) {integers.Add(i);}
}
// now you have a list of integers
// if using decimal, use decimal instead of integer


0 commentaires

3
votes

Certaines réponses intelligentes LINQ sont déjà fournies, voici ma solution étape par étape étendue qui permet également d'ignorer les numéros invalides:

//Read input string
Console.Write("Input numbers separated by space: ");
string inputString = Console.ReadLine();
//Split by spaces
string[] splittedInput = inputString.Split(' ');
//Create a list to store all valid numbers
List<int> validNumbers = new List<int>();
//Iterate all splitted parts
foreach (string input in splittedInput)
{
    //Try to parse the splitted part
    if (int.TryParse(input, out int number) == true)
    {
        //Add the valid number
        validNumbers.Add(number);
    }
}
//Print all valid numbers
Console.WriteLine(string.Join(", ", validNumbers));


0 commentaires