Обратные гласные в строке в C# - PullRequest
1 голос
/ 10 апреля 2020

Я пытаюсь взять строку в качестве ввода и вернуть строку только с обращенными гласными. Это без ошибок, но не без ошибок. Ошибка на Test19 () и Test20 . Не хватает идей, как это исправить или почему у меня проблемы с этим тестом. Все остальные тесты проходят. Первый блок кода - это мой код, за которым следует тест, который я создал во втором блоке.

Это ссылка на страницу, которая содержит более подробную информацию о тесте, который я провел. Nunit.org StringAssert (NUnit 2.2.3)

using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Vowels
{
    public class reverseVowels
    {
        public static bool IsVowel(char c)
        {
            char[] vowels = new[] { 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U' };
            return vowels.Any(ch => ch == c);
        }

        public static string reverseVowelsOfString(string s)
        {
            List<char> list = (from char c in s
                               where IsVowel(c)
                               select c).ToList();
            StringBuilder sb = new StringBuilder();

            foreach (char v in s)
            {
                if (IsVowel(v))
                {
                    sb.Append(list.Last());
                    list.Remove(list.Last());
                }
                else
                {
                    sb.Append(v);
                }
            }

            return sb.ToString();
        }
    }
}
using NUnit.Framework;

namespace Vowels
{
    public class VowelsTest
    {
        [Test]
        public void Test1() => StringAssert.Contains("hollo, werld", reverseVowels.reverseVowelsOfString("hello, world"));

        [Test]
        public void Test2() => StringAssert.Contains("cadisegnol", reverseVowels.reverseVowelsOfString("codesignal"));

        [Test]
        public void Test3() => StringAssert.Contains("UOaIye", reverseVowels.reverseVowelsOfString("eIaOyU"));

        [Test]
        public void Test4() => StringAssert.Contains("", reverseVowels.reverseVowelsOfString(""));

        [Test]
        public void Test5() => StringAssert.Contains(" ", reverseVowels.reverseVowelsOfString(" "));

        [Test]
        public void Test6() => StringAssert.Contains(".a", reverseVowels.reverseVowelsOfString(".a"));

        [Test]
        public void Test7() => StringAssert.Contains("ia", reverseVowels.reverseVowelsOfString("ai"));

        [Test]
        public void Test8() => StringAssert.Contains("Aa", reverseVowels.reverseVowelsOfString("aA"));

        [Test]
        public void Test9() => StringAssert.Contains(".,", reverseVowels.reverseVowelsOfString(".,"));

        [Test]
        public void Test10() => StringAssert.Contains("ab", reverseVowels.reverseVowelsOfString("ab"));

        [Test]
        public void Test11() => StringAssert.Contains("0P", reverseVowels.reverseVowelsOfString("0P"));

        [Test]
        public void Test12() => StringAssert.Contains("!!!", reverseVowels.reverseVowelsOfString("!!!"));

        [Test]
        public void Test13() => StringAssert.Contains("a a", reverseVowels.reverseVowelsOfString("a a"));

        [Test]
        public void Test14() => StringAssert.Contains("abb", reverseVowels.reverseVowelsOfString("abb"));

        [Test]
        public void Test15() => StringAssert.Contains("1b1", reverseVowels.reverseVowelsOfString("1b1"));

        [Test]
        public void Test16() => StringAssert.Contains("abba", reverseVowels.reverseVowelsOfString("abba"));

        [Test]
        public void Test17() => StringAssert.Contains("c#dc", reverseVowels.reverseVowelsOfString("c#dc"));

        [Test]
        public void Test18() => StringAssert.Contains("......a.....", reverseVowels.reverseVowelsOfString("......a....."));

        [Test]
        public void Test19() => StringAssert.Contains("raca e car", reverseVowels.reverseVowelsOfString("race a car"));

        [Test]
        public void Test20() => StringAssert.Contains("SorE was I ere I saw eros.", reverseVowels.reverseVowelsOfString("Sore was I ere I saw Eros."));

        [Test]
        public void Test21() => StringAssert.Contains("a man, a plan, a canal -- PanamA", reverseVowels.reverseVowelsOfString("A man, a plan, a canal -- Panama"));
    }
}
  X Test19 [43ms]
  Error Message:
     Expected: String containing "raca e car"
  But was:  "raca a cer"

  Stack Trace:
     at Vowels.VowelsTest.Test19() in C:\Users\scott\Desktop\reverseVowelsOfString\test.cs:line 62

  X Test20 [< 1ms]
  Error Message:
     Expected: String containing "SorE was I ere I saw eros."
  But was:  "Soro wEs a arI I sew eres."

  Stack Trace:
     at Vowels.VowelsTest.Test20() in C:\Users\scott\Desktop\reverseVowelsOfString\test.cs:line 65

Test Run Failed.
Total tests: 21
     Passed: 19
     Failed: 2
 Total time: 1.1547 Seconds

Ответы [ 2 ]

5 голосов
/ 10 апреля 2020

Я бы сделал несколько изменений. Во-первых, я бы переместил создание списка гласных в одноразовый распределенный член класса, чтобы избежать ненужных распределений. Я бы также сделал это HashSet<char> по соображениям эффективности:

    private static readonly HashSet<char> _vowels = new HashSet<char>(new[] { 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U' });

Теперь ваш метод IsVowel() можно упростить до:

    public static bool IsVowel(char c) => _vowels.Contains(c);

Для метода, выполняющего все работать, я бы дал переменным более значимые имена. vowels вместо list и c вместо v, поскольку мы знаем, что это символ, но не обязательно гласный (я полагаю, это то, что означало v).

I я также поместил бы список гласных в Stack<char>, чтобы вы могли легко вытолкнуть их при необходимости.

    public static string reverseVowelsOfString(string s)
    {
        Stack<char> vowels = new Stack<char>(s.Where(IsVowel));
        StringBuilder sb = new StringBuilder();

        foreach (char c in s)
        {
            if (IsVowel(c))
            {
                sb.Append(vowels.Pop());
            }
            else
            {
                sb.Append(c);
            }
        }

        return sb.ToString();
    }
4 голосов
/ 10 апреля 2020

Это происходит потому, что в тестовом примере 19;

list = { 'a', 'e', 'a', 'a' }

И когда вы пытаетесь удалить list.Last (), который является 'a', удаляется первый элемент.

sb.Append(list.Last()); // appends the last element in the list, which is OK,
list.Remove(list.Last()); // since list.Last() is 'a', removes the first 'a' element in the list.

Решение так же просто, как:

sb.Append(list.Last());
list.RemoveAt(list.Count - 1); // Remove the last item in the list.

Надеюсь, это поможет.

...