Placing spaces between letters of a text

Asked

Viewed 1,367 times

-4

As if a certain string as "Something" was with spaces between the letters as for example "A l g u m a C o i s a"; as I do it in C#?

  • Is it for all words to be capitalized? What happens to the existing blank space? What if there’s room at the beginning or end of the sentence? Not knowing where to reach any path is valid and there is a valid question for this site, we need questions with defined criteria and there may be a right answer.

  • 3

    Possible duplicate of Doubt with the language C#

  • You have already asked the question at https://answall.com/questions/324350/d%C3%Bavida-com-a-linguagem-c/324372#324372 in the question there are already answers that address the same subject and that address the efficiency problems mentioned in other answers more elegantly.

3 answers

3

The two current answers are with problems and do not produce the expected result, at least not in all situations and as the example shown in the question. If one of those answers is right then the question is wrong.

You should avoid problems with extra spaces. If by chance you don’t need to take care of the white spaces, you can simplify the code (if the AP pronounces I can by a simpler version), but it’s still much better to do the efficient way that is the main reason I posted. I find bad options that teach to do inefficiently (at least should have a warning)

In addition there is inefficiency in both by generating multiple allocations of string which is something that will generate a lot of pressure on Garbage Collector, what matters a lot in strings which are considered slow when compared to number manipulations and which are often used in loops which makes a huge difference in large volumes. Must use StringBuilder.

So it seems more correct:

using static System.Console;
using System.Text;

public class Program {
    public static void Main() {
        var frase = " Alguma coisa ";
        var espacado = new StringBuilder(frase.Length * 2 - 1);
        var i = 0;
        for (; i < frase.Length && frase[i] == ' '; i++);
        espacado.Append(char.ToUpper(frase[i]));
        for (i++; i < frase.Length; i++) {
            if (frase[i] != ' ') {
                espacado.Append(' ');
                espacado.Append((i == 0 || frase[i - 1] == ' ') ? char.ToUpper(frase[i]) : char.ToLower(frase[i]));
            }
        }
        WriteLine("|" + espacado + "|");
    }
}

I don’t really like flag, almost always it is gambiarra or laziness to find the correct form, or even failure of the language to be able to express that, but in this case I think it simplifies the code:

using static System.Console;
using System.Text;

public class Program {
    public static void Main() {
        var frase = " Alguma coisa ";
        var espacado = new StringBuilder(frase.Length * 2 - 1);
        var primeiro = true;
        for (var i = 0; i < frase.Length; i++) {
            if (frase[i] == ' ') continue;
            if (!primeiro) {
                espacado.Append(' ');
            }
            primeiro = false;
            espacado.Append((i == 0 || frase[i - 1] == ' ') ? char.ToUpper(frase[i]) : char.ToLower(frase[i]));
        }
        WriteLine("|" + espacado + "|");
    }
}

Behold working in the ideone, And in the .NET Fiddle. Also put on the Github for future reference (and the second form).

  • I voted +1 in your reply. I realized that the StringBuilder is faster and is a good approach.

  • Yeah, but the right thing about that question was that no one answered, look at the mess it’s become. That’s why I think you need to close certain things soon, or when it was too late, disregard what was answered, the tool is wrong and encourages a lot of answers without being able to answer.

  • I agree, this was the primordial mistake I made, I had talked to the staff in the chat and was considering deleting my answer. But looking at it from another angle, your response can help other people, and mine at least reinforces it. Next time I’ll be more cautious and close soon to avoid these things ;)

  • I already had an answer.

1

In Linq there is the method Select which allows you to design each element of a sequence. Remember that a string is nothing more than a sequence of characters.

Take an example:

var str = "Alguma coisa";
var r = string.Concat(str.Select((s) => " " + s.ToString()));
Write(r);

Exit:

A l g u m a c o i s a

He seeks the elements of string, what I did was concatenate with a blank " " with the current element and as the Select method returns a enumerable we use the Concat to concatenate all into one string only.

See working on .NET Fiddle.


Editing

It was my failure not to realize that you have to keep the first letters capitalized on each word. So, I created a new version correcting this fault and with some modifications.

See the code:

using static System.Console;
using System.Linq;
using System.Globalization;
using System.Text.RegularExpressions;

public class Program {
    public static void Main() {     
        var str = "  Alguma coisa outrA i   i coIsA ";

        var resultado = Espacar(RemoverTodosEspacos(Capitalizar(str, false, "pt-BR")));
        Write($"|{resultado}|");        
    }

    private static string Capitalizar(string texto, bool acronimo, string cultura) { 
        if (string.IsNullOrWhiteSpace(texto) || string.IsNullOrWhiteSpace(cultura)) {
            return null;
        }
        TextInfo info = new CultureInfo(cultura, false).TextInfo;       
        if (acronimo) {
            return info.ToTitleCase(texto);
        }
        return info.ToTitleCase(texto.ToLower());
    }

    private static string Espacar(string texto) {
        if (string.IsNullOrWhiteSpace(texto)) {
            return null;
        }       
        return string.Concat(texto.Select((s, i) => " " + s.ToString())).TrimStart();
    }

    private static string RemoverTodosEspacos(string texto) { 
        if (string.IsNullOrWhiteSpace(texto)) { 
            return null;
        }
        return Regex.Replace(texto, @"\s+", "");
    }
}

Exit

|A l g u m a C o i s a O u t r a I I C o i s a|

The first thing you have to do is a capitalisation in string to ensure that the first letters are uppercase. The method that does this is the Totitlecase class TextInfo, and to consider the use of acronyms and cultures created the method Capitalizar() that allows you to define which culture will be, or if you will ignore the acronyms.

I assumed that AP only wants a space between letters or characters, so I created a method RemoverTodosEspacos() to remove all whitespace from the string and the Tabs it contains in the string, and this method uses a regular expression.

And finally I created the method Espacar() which is the same approach above, except that it removes space at the beginning of the string and checks whether the string is valid.

See the new code working on .NET Fiddle.

Important

The above approach may not be as performative as the Maniero.

The StringBuilder is faster and you can compare here and read more here. Of course if performance is the priority due to the volume of data and the amount of changes that will occur in string I strongly recommend you take the approach of Maniero.

Also I did not do all the tests in the code I created and it needs improvements, even in terms of performance or possible anomalies that may occur. Therefore, I suggest you improve it and dig deeper into the subject.

Sources:

Converting string to title case

Efficient way to remove ALL whitespace from String?

0

Make a foreach that will read every position of this string, example:

using System;

public class Program
{
    public static void Main()
    {
        string frase = "Alguma coisa".Replace(" ","");
        string result = "";
        foreach(var f in frase) {
            if (!string.IsNullOrEmpty(result)) result += " ";
            result += f;
        }
        Console.WriteLine(result);
    }
}

Online Example

Every item read from this string is a char and with that you can assemble a new string with the spaces.

  • I would just like to understand the negative vote? Is there something wrong that I didn’t see?

  • 2

    Man, I believe that the author of the question is very lay in C#, by the punctuation I also believe that this should be his first question in SO-pt, so whoever is the person to answer, if he makes use of some structure or method, it would be good for the person to explain what each one does. I never had to do this, but I understood why I’ve been dealing with C# for a while now, but looking from another perspective (the newbie in the case), you did more than you explained. abs!

  • @Luckasfujimoto this does not justify taking a negative vote. At no time also the answer is so complicated to understand, is the simplest way to make the other answer used Linq imagine you much more complicated.

  • 2

    That’s exactly why I upvoted your answer. Because if you’re going to consider what’s in each method, it’s actually much more code than what you’ve implemented for response. Most likely whoever gave upvote on the other answer knows what each method does, the questioner if I’m not mistaken can not even vote yet due to low score.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.