Как решить задачу: "Введите строку произвольной длины и подсчитайте процент вхождения заданного символа в строку" на c#

Код ниже при компиляции выдаёт тонну ошибок Unhandled Exception:


    Console.WriteLine("Введите строку произвольной длины:");
    string str = Console.ReadLine();
    Console.WriteLine("Введите символ для того что бы найти процент его вхождения в строку:");
    string sym = Console.ReadLine();
    int length = str.Length;
    char[] strArr = str.ToCharArray();
    char[] symArr = sym.ToCharArray();
    int counter = 0;
    for (int i = 0; i < length; i++)
    {
        if(strArr[i] == symArr[int.Parse(sym)])
        {
            counter++;
        }
    }
    double lengthDouble = Convert.ToDouble(length);
    double counterDouble = Convert.ToDouble(counter);
    double prc = (lengthDouble / counterDouble) * 100;
    Console.WriteLine($"Процент вхождения символа {sym} равен {prc}%");

Ошибок в самом IDE нету. Unhandled Exception появляется после ввода данных на 4 строке.

Вот и ошибки:


    Unhandled exception. System.FormatException: Input string was not in a correct f
    ormat.
       at System.Number.ThrowOverflowOrFormatException(ParsingStatus status, TypeCod
    e type)
       at System.Number.ParseInt32(ReadOnlySpan`1 value, NumberStyles styles, Number
    FormatInfo info)
       at System.Int32.Parse(String s)
       at weirdFlexButOk.Program.Main(String[] args) in C:\Users\User\source\repos\w
    eirdFlexButOk\weirdFlexButOk\Program.cs:line 19

В массивах чайник, в интернете нормального ответа не нашел, как можно избавится от всех этих ошибок?


Ответы (3 шт):

Автор решения: Aziz Umarov

Решите задачу простой заменой подстроки на пустую.

100 - sourceString.Replace(subString, "").Length/sourceString.Length*100

→ Ссылка
Автор решения: return
// оптимальная реализация - 0 динамических выделений памяти
int FindCount(RedaOnlySpan<char> input, ReadOnlySpan<char> pattern)
{
    var cnt = 0;

    for (var i = 0; i <= input.Length - pattern.Length; i++)
        if (input.Slice(i, pattern.Length) // выделяем фрагмент
            .Equals(pattern, StringComparision.Ordinal)) // сравниваем с образцом
            cnt++;

    return cnt;
}
void Run()
{
    var str = ...;
    var sym = ...;
    var symCnt = FindCount(str, sym);
    var symPrc = (double)(symCnt * sym.Length) / str.Length;

    Console.Write("Процент вхождения: ");
    Console.WriteLine(symPrc.ToString("P"));
}
Пример
Введите строку произвольной длины:
abc_Abc_123_
Введите символ для того что бы найти процент его вхождения в строку:
abc
Процент вхождения: 25.00 %
→ Ссылка
Автор решения: Andrei Khotko

Идея у вас правильная, но в предложенном вами коде есть несколько ошибок/недостатков:

  1. Ваш код падает с ошибкой, потому что вы зачем-то пытаетесь преобразовать введенный символ в число в этой строке:

    if(strArr[i] == symArr[int.Parse(sym)])
    
  2. Вы неправильно считаете процент входжения. Правильная формула: Процент вхождения = количество повторений символа / число символов в строке. У вас же в коде процент вычисляется по-другому. Вам нужно "перевернуть" дробь.

  3. Если вам нужно прочитать единственный символ, то вы можете пойти двумя путями:

  • прочитать строку var syms = Console.ReadLine() и взять первый символ из строки var sym = syms[0],
  • прочитать один символ с помощью var sym = Console.ReadKey().KeyChar

С учетом вышеуказанных недостатков ваш исправленный код будет в итоге выглядеть так:

Console.WriteLine("Введите строку произвольной длины:");
string str = Console.ReadLine();
Console.WriteLine("Введите символ для того что бы найти процент его вхождения в строку:");
char sym = Console.ReadKey().KeyChar;
Console.WriteLine();

int length = str.Length;
char[] strArr = str.ToCharArray();
int counter = 0;
for (int i = 0; i < length; i++)
{
    if (strArr[i] == sym)
    {
        counter++;
    }
}
double lengthDouble = Convert.ToDouble(length);
double counterDouble = Convert.ToDouble(counter);
double prc = (counterDouble / lengthDouble) * 100;
Console.WriteLine($"Процент вхождения символа {sym} равен {prc}%");
→ Ссылка