Свинья Латинский Переводчик выплевывает несколько строк? C#

Так что у меня есть Pig Latin Translator, который поддерживает несколько слов. Но всякий раз, когда я ввожу какие-то слова (для этого мы просто используем, например, "поезд Теодора с банановыми яблоками и шоколадными ножницами".) Он будет выплевывать переведенные слова правильно, но повторяется! Вот мой код:

namespace Pig_Latin_Translator
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    List<string> vowels = new List<string>();
    List<string> specials = new List<string>();

    private void TranslateButton_Click(object sender, EventArgs e)
    {
        String[] parts = TranslateBox.Text.Split();
        foreach (string s in specials)
        {
            if (TranslateBox.Text.Contains(s) || TranslateBox.Text == "\"")
            {
                TranslateOutput.Text = "";
                MessageBox.Show("No Special Characters!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                break;
            }
            else
            {
                 foreach (String part in parts)
                {
                    foreach (String v in vowels)
                    {
                        if (part.Substring(0, 1) == v)
                        {
                            TranslateOutput.Text = TranslateOutput.Text + " " + part + "ay";
                            break;
                        }
                        else
                        {
                            if (part.Substring(0, 2) == "sh" || part.Substring(0, 2) == "ch" || part.Substring(0, 2) == "th" || part.Substring(0, 2) == "tr")
                            {
                                string SwitchP = part.Substring(2) + part.Substring(0, 2);
                                TranslateOutput.Text = TranslateOutput.Text + " " + SwitchP + "ay";
                                break;
                            }
                            else
                            {
                                string Switch = part.Substring(1) + part.Substring(0, 1);
                                TranslateOutput.Text = TranslateOutput.Text + " " + Switch + "ay";
                                break;
                            }
                        }
                    }
                }
            }
        }
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        vowels.Add("a");
        vowels.Add("e");
        vowels.Add("i");
        vowels.Add("o");
        vowels.Add("u");

        specials.Add("`");
        specials.Add("1");
        specials.Add("2");
        specials.Add("3");
        specials.Add("4");
        specials.Add("5");
        specials.Add("6");
        specials.Add("7");
        specials.Add("8");
        specials.Add("9");
        specials.Add("0");
        specials.Add("-");
        specials.Add("=");
        specials.Add("[");
        specials.Add("]");
        specials.Add(@"\");
        specials.Add(";");
        specials.Add("'");
        specials.Add(",");
        specials.Add(".");
        specials.Add("/");

        specials.Add("~");
        specials.Add("!");
        specials.Add("@");
        specials.Add("#");
        specials.Add("$");
        specials.Add("%");
        specials.Add("^");
        specials.Add("&");
        specials.Add("*");
        specials.Add("(");
        specials.Add(")");
        specials.Add("_");
        specials.Add("+");
        specials.Add("{");
        specials.Add("}");
        specials.Add("|");
        specials.Add(":");
        specials.Add("\"");
        specials.Add("<");
        specials.Add(">");
        specials.Add("?");
    }

    private void AboutButton_Click(object sender, EventArgs e)
    {
        MessageBox.Show("Pig Latin is a fake language. It works by taking the first letter (Or two if it's a pair like 'th' or 'ch') and bringing it to the end, unless the first letter is a vowel. Then add 'ay' to the end. So 'bus' becomes 'usbay', 'thank' becomes 'ankthay' and 'apple' becomes 'appleay'.", "About:", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

}

Какие результаты, если вы набрали "банановые ножницы с шоколадом и поездом Теодора":

"ananabay appleay earsshay ocolatechay heodoreTay aintray" повторяется более 10 раз.

КСТАТИ: Извините, если вы не можете ответить, потому что я знаю, что есть много кода. Но это не важно, потому что вещь все еще полезна. Просто это не должно происходить и действовать мне на нервы. И я знаю, что есть еще много глюков и многое другое, но я хочу сначала решить эту проблему.

3 ответа

Решение

Вы вкладываете свой код в два цикла, которые не должны быть вложены в

foreach (string s in specials)

а также

foreach (String v in vowels)

Ваш break заявления вытащить вас из неприятностей для одного, но не другого.

Вы можете избежать этих петель полностью, если вы используете .Any(...) сказуемое.

Вот как может выглядеть ваш код:

private void TranslateButton_Click(object sender, EventArgs e)
{
    TranslateOutput.Text = "";
    if (specials.Any(s => TranslateBox.Text.Contains(s)))
    {
        MessageBox.Show("No Special Characters!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
    }
    else
    {
        String[] parts = TranslateBox.Text.Split();
        foreach (var part in parts)
        {
            var index = 1;
            if (vowels.Any(v => part.Substring(0, 1).ToLower() == v))
            {
                index = 0;
            }
            else if (new [] { "sh", "ch", "th", "tr", }.Contains(part.Substring(0, 2).ToLower()))
            {
                index = 2;
            }
            TranslateOutput.Text += " " + part.Substring(index) + part.Substring(0, index);
        }
    }
    TranslateOutput.Text = TranslateOutput.Text.TrimEnd();
}

Это сводит его к одному foreach петля, которая вам действительно нужна.

Вы также можете получить свой код для инициализации vowels а также specials вплоть до этого:

vowels.AddRange("aeiou".Select(x => x.ToString()));
specials.AddRange(@"`1234567890-=[]\;',./~!@#$%^&*()_+{}|:""<>?".Select(x => x.ToString()));

У вас есть небольшая логическая проблема в ваших циклах.

Ваш внешний цикл:

foreach( string s in specials ) {

... проходит по всем 42 символам в вашем списке специальных символов.

Ваш внутренний цикл

foreach( String part in parts ) {

... затем исполняется 42 раза. Так что для вашего примера из шести слов вы на самом деле выполняете свою свинью латинскую конвертацию 252 раза.

Если вы извлекаете внутренний цикл из внешнего, ваши результаты лучше. Как это:

foreach( string s in specials ) {
    if( TranslateBox.Text.Contains( s ) || TranslateBox.Text == "\"" ) {
        TranslateOutput.Text = "";
        MessageBox.Show( "No Special Characters!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Warning );
        return;
    }
}

String[] parts = TranslateBox.Text.Split();
foreach( String part in parts ) {
    foreach( String v in vowels ) {
        if( part.Substring( 0, 1 ) == v ) {
            TranslateOutput.Text = TranslateOutput.Text + " " + part + "ay";
            break;
        }
        else {
            if( part.Substring( 0, 2 ) == "sh" || part.Substring( 0, 2 ) == "ch" || part.Substring( 0, 2 ) == "th" || part.Substring( 0, 2 ) == "tr" ) {
                string SwitchP = part.Substring( 2 ) + part.Substring( 0, 2 );
                TranslateOutput.Text = TranslateOutput.Text + " " + SwitchP + "ay";
                break;
            }
            else {
                string Switch = part.Substring( 1 ) + part.Substring( 0, 1 );
                TranslateOutput.Text = TranslateOutput.Text + " " + Switch + "ay";
                break;
            }
        }
    }
}

Несколько более сжатой реализацией будет:

private void TranslateButton_Click( object sender, EventArgs e )
{
    char[] specials = "`1234567890-=[]\";',./~!@#$%^&*()_+{}|:\\<>?".ToArray();
    char[] vowels = "aeiou".ToArray();

    TranslateOutput.Text = String.Empty;

    if( TranslateBox.Text.IndexOfAny( specials ) > -1 ) {
        MessageBox.Show( "No Special Characters!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Warning );
        return;
    }

    String[] parts = TranslateBox.Text.Split();
    foreach( String part in parts ) {
        int firstVowel = part.IndexOfAny( vowels );
        if( firstVowel > 0 ) {
            TranslateOutput.Text += part.Substring( firstVowel ) + part.Substring( 0, firstVowel ) + "ay ";
        }
        else {
            TranslateOutput.Text += part + "ay ";
        }
    }

    TranslateOutput.Text = TranslateOutput.Text.TrimEnd();
}

В этом примере я создаю два массива символов для специальных и гласных. Затем я могу использовать рамки IndexOfAny метод для поиска любого из символов в массиве и возврата индекса первого вхождения. Это найдет первый специальный, если таковые имеются, в первом цикле и первый гласный во втором цикле. Как только я получу этот индекс из слова, я смогу разобрать слово на латынь. Обратите внимание, что я проверяю ноль в качестве индекса гласного, так как в латинском языке свинца ведущий гласный остается там, где он есть, а "ay" просто добавляется в конец слова.

Вы повторяете свои слова один раз для каждого специального символа. Ваш foreach пройти через ваши слова и перевести это внутри вашего foreach проверить, содержит ли текстовое поле какие-либо специальные символы.

Другими словами, вы будете выполнять перевод один раз для каждого специального символа.

Вы хотите переместить foreach (String part in parts) из вашего foreach (string s in specials)

Другие вопросы по тегам