Как перечислить корни числа в c#

Я пытаюсь написать код, в котором перечислены корни данного числа. Это то, что пока что я сделал. В результате я получаю 2*2*5*5, что верно, но вместо этого я хочу получить это: 2^2*5^2.

public partial class Form1 : Form
{
    List<int> divisor;

    public Form1()
    {
        InitializeComponent();
    }

    private void list_Click(object sender, EventArgs e)
    {
        int number;
        divisor = new List<int>();

        showroot.Text = "";
        number = Int32.Parse(usernum.Text);

        for (int i = 2; i <= number; i++)
        {
            if (number % i == 0)
            {
                divisor.Add(i);
                number = number / i;
                i = 1;
            }
        }

        for (int i = 0; i < divisor.Count; i++)
        {
            print(""+ divisor[i]);
        }
    }

    private void print(String text)
    {
        if (showroot.Text != "")
        {
            showroot.Text = showroot.Text + "*" + text;
        }
        else
        {
            showroot.Text = text;
        }
    }
  }

Я попытался проверить, сколько одинаковых корней и посчитать их на два для вложенных операторов, но это приводит к другим ошибкам внутри.

for (int i = 0; i < divisor.Count; i++) {
  for (int a = 0; i < divisor.Count; a++) {
    if (i == a) {
      base[i]++;
    }
  }
}

Что делать?

Вы имеете в виду простые множители, а не корнеплоды?

lurker 11.04.2018 12:14

Спасибо за исправление. да, именно это я имел в виду.

gks 11.04.2018 12:45
0
2
121
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Наивной реализацией было бы изменение вашего for на это:

for (int i = 2; i <= number; i++)
{
    count = 0;
    while (number % i == 0)
    {            
        number = number / i;
        count++;
    }

    if (count > 0)
    {
       divisor.Add(i);
       powers.Add(count);
    }
 }

Однако можно сделать много оптимизаций.

Разделите задачу на простые для реализации части, методы извлечения:

Прежде всего, соберем все простые делители (делители могут повторяться):

private static IEnumerable<int> AllPrimeDivisors(int value) {
  if (value <= 1)
    yield break;

  for (; value % 2 == 0; value /= 2)
    yield return 2;

  int n = (int)(Math.Sqrt(value) + 0.5);

  for (int d = 3; d <= n; d += 2) {
    while (value % d == 0) {
      yield return d;

      value /= d; 
      n = (int)(Math.Sqrt(value) + 0.5);
    }
  }

  if (value > 1)
    yield return value;
}

Затем объедините их в требуемый формат (мы должны GroupBy одинаковые - повторяющиеся - делители и представлять их либо в формате divisor, либо в формате divisor^power)

private static string Solve(int value) {
  var terms = AllPrimeDivisors(value)
    .GroupBy(divisor => divisor)
    .Select(group => group.Count() == 1 
       ? $"{group.Key}"
       : $"{group.Key}^{group.Count()}");

  return string.Join("*", terms);  
}

Наконец, добавьте UI:

private void list_Click(object sender, EventArgs e) {
  if (int.TryParse(usernum.Text, out var number))
    showroot.Text = Solve(number);
  else
    showroot.Text = "Incorrect Input, Syntax Error";
}

Тесты:

int[] tests = new int[] {
  3, 5, 9, 12, 16, 41, 81, 100,  
};

var result = tests
  .Select(item => $"{item,3} == {Solve(item)}");

Console.Write(string.Join(Environment.NewLine, result)); 

Исход:

  3 == 3
  5 == 5
  9 == 3^2
 12 == 2^2*3
 16 == 2^4
 41 == 41
 81 == 3^4
100 == 2^2*5^2

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