Я подозреваю, что вы просто не распечатываете их правильно, трудно сказать, так как вы не включили этот код, но, если вы добавите main
таким образом:
int main(void) {
SLLI * x = PrimeFactor(NULL, 72);
while (x != NULL) {
printf("%d\n", x->data);
x = x->next;
}
return 0;
}
, тогда вы будете получите как 2
, так и 3
, которые являются единственными простыми коэффициентами 72
: 72 = 2<sup>3</sup>3<sup>2</sup> (8 x 9)
.
Аналогично, 120
дает вам 2
, 3
и 5
: 120 = 2<sup>3</sup>3<sup>1</sup>5<sup>1</sup> (8 x 3 x 5)
.
Несколько других моментов для рассмотрения:
Я не уверен, почему вы проходите в prime
к функции, так как вы все равно перезаписываете ее. Вы должны удалить это из определения функции и просто иметь локальную переменную для хранения информации.
При проверке на простоту вам не нужно go, чтобы вдвое уменьшить значение, просто на его площадь root. Таким образом, лучшим значением l oop будет: for (j = 2; j * j <= i; j++)
.
Чётный лучше проверяет, что кроме 2
и 3
каждое простое число имеет вид 6n + 1
или 6n + 5
. Это потому, что:
6n + 0 = 6n
, кратное шести; 6n + 2 = 2(3n + 1)
, кратное двум; 6n + 3 = 3(2n + 1)
, кратное трем ; 6n + 4 = 2(3n + 2)
, кратное двум;
, оставляя только 6n + 1
и 6n + 5
в качестве кандидатов (не каждый один из них является простым числом (например, 6(4) + 1 = 25
), но простые числа могут быть извлечены исключительно из этого набора).
Таким образом, еще лучшим тестом на простоту является следующая функция:
// Function for checking primality.
int isPrime(int number) {
// Special cases.
if ((number == 2) || (number == 3)) return 1;
if ((number % 2 == 0) || (number % 3 == 0)) return 0;
if (number < 5) return 0;
// Efficient selection of candidate primes, starting at 5, adding
// 2 and 4 alternately: 5, 7, 11, 13, 17, 19, 21, 25, 27, ...
for (
int candidate = 5, add = 2;
candidate * candidate <= number;
candidate += add, add = 6 - add
) {
if (number % candidate == 0) {
return 0;
}
}
return 1;
}
Использование этой функции и добавление некоторых дополнительных функций для выгрузки и освобождения списка, а также предоставление тестового набора main
дает следующую полную программу:
#include <stdio.h>
#include <stdlib.h>
typedef struct sListItem
{
int data;
struct sListItem *next;
} ListItem;
// Function for checking primality.
int isPrime(int number) {
// Special cases.
if ((number == 2) || (number == 3)) return 1;
if ((number % 2 == 0) || (number % 3 == 0)) return 0;
if (number < 5) return 0;
// Efficient selection of candidate primes, starting at 5, adding
// 2 and 4 alternately: 5, 7, 11, 13, 17, 19, 21, 25, 27, ...
for (int candidate = 5, add = 2; candidate * candidate <= number; candidate += add, add = 6 - add)
if (number % candidate == 0)
return 0;
return 1;
}
// Function for returning list of prime factors.
ListItem *primeFactorList(int number) {
ListItem *retVal = NULL;
ListItem *lastItem;
// Analyse possible factors, up to half of number.
for (int divisor = 2; divisor <= number / 2 + 1; divisor++) {
if ((number % divisor == 0) && isPrime(divisor)) {
if (retVal == NULL) {
// Adding first item to list.
retVal = lastItem = malloc(sizeof(ListItem));
lastItem->data = divisor;
lastItem->next = NULL;
} else {
// Adding subsequent items to list.
lastItem->next = malloc(sizeof(ListItem));
lastItem = lastItem->next;
lastItem->data = divisor;
lastItem->next = NULL;
}
}
}
return retVal;
}
// Dump a list.
void dumpList(int value, ListItem *head) {
printf("%d:", value);
while (head != NULL) {
printf(" -> %d", head->data);
head = head->next;
}
putchar('\n');
}
// Free a list.
void freeList(ListItem *head) {
while (head != NULL) {
ListItem *toDelete = head;
head = head->next;
free(toDelete);
}
}
// Test program.
int main(int argc, char *argv[]) {
static int data[] = { 10, 24, 72, 120, 125, -1 };
for (int *ptr = &(data[0]); *ptr >= 0; ptr++) {
ListItem *list = primeFactorList(*ptr);
dumpList(*ptr, list);
freeList(list);
}
return 0;
}
И компиляция и запуск, который показывает результаты тестового набора (с моими добавленными комментариями справа, и не стесняйтесь добавлять любые дополнительные значения в массив data
, если вы хотите больше тестирования):
10: -> 2 -> 5 2 x 5
24: -> 2 -> 3 2^3 x 3
72: -> 2 -> 3 2^3 x 3^2
120: -> 2 -> 3 -> 5 2^3 x 3 x 5
125: -> 5 5^3