Ручной подсчет | C#

Как мне из этого:

rez += (int)Math.Pow(p, x.Length - 1 - i) * (int)(x[i]);

Вывести формулу, для подсчета на листке.

x - это любое целое число

Вот код:

По нажатию кнопки, я отправляю значение в функцию Reshi(x)

private void button1_Click(object sender, EventArgs e)
{
        string x = textBox1.Text;

        label6.Text = Convert.ToString(x.Length);
        listBox1.Items.Add(Reshi(x));
}

Допустим значение 10. В ListBox я получаю - 1567

Сама функция Reshi(x):

public static int Reshi(string x)
    {

        int p = 31;
        int rez = 0; //Результат вычисления 
        for (int i = 0; i < x.Length; i++)
        {

            rez += (int)Math.Pow(p, x.Length - 1 - i) * (int)(x[i]); 
        }
        return rez;

    }

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

Автор решения: aepot

Алгоритм Рабина-Карпа. Теперь понятнее. Могли же сразу это в вопросе написать?

Чтобы посчитать на бумаге, вам нужно знать код каждого симовла в строке. То есть значение (int)(x[i]). Без этого значения вы не посчитаете.

Math.Pow() - это возведение степень, а (int) перед ним - это отрезание дробной части, что является грубой ошибкой при подобных вычислениях, так как при вычислениях с плавающей точной существует погрешность, и вы можете например получить 5.99999999 (и это нормально), что преобразуется просто в 5. Правильнее формула выглядела бы так.

rez += (int)Math.Round(Math.Pow(p, x.Length - 1 - i)) * (int)(x[i]);

Тогда можно посчитать. К примеру, пусть x = "13", то есть строка, содержащая число 13.

По таблице символов, код символа "1" - это 49, код символа "3" соответственно 51.

Длина числа - 2 символа, p = 31. Считаем

алгоритмически так: res = res + (p ^ (x.Length - 1 - i)) * код x[i]

первый символ: (31 ^ (2 - 1 - 0)) * 49 = 1519
второй символ: (31 ^ (2 - 1 - 1)) * 51 = 51
1519 + 51 = 1570
→ Ссылка