Страница 1 из 2
Найти наименьшее общее кратное массива
Добавлено: 08 янв 2010, 12:21
Vaiper
Найти наименьшее общее кратное массива.
Массив целочисленный, вводится с клавы.
Желательно на Си, но можно и на Си++.
заранее благодатен.
Re: Найти наименьшее общее кратное массива
Добавлено: 09 янв 2010, 04:57
BulldozerBSG
Если это работа то это не в этот раздел и всякая работа должна быть оплачиваемая, а если непонятен алгоритм то это не вопрос С или С++, а вопрос алгоритмов. А алгоритм могу объяснить если надо

Re: Найти наименьшее общее кратное массива
Добавлено: 09 янв 2010, 08:39
Vaiper
BulldozerBSG писал(а):Если это работа то это не в этот раздел и всякая работа должна быть оплачиваемая, а если непонятен алгоритм то это не вопрос С или С++, а вопрос алгоритмов. А алгоритм могу объяснить если надо
Это не работа, я сам попробую написать код, а с алгоритмом проблемы.И еще не знаю как на Си написать:
"Берем 1-й элемент массива, пусть а[0] и делим его на 2 до тех пор пока делится без остатка, затем делим на 3 и т.д.(т.е. раскладываем число для вычисления НОК)".Вот здесь парюсь.
Re: Найти наименьшее общее кратное массива
Добавлено: 09 янв 2010, 18:31
BulldozerBSG
Вот следующие куски кода изображаю одну из реализаций алгоритма. Смысл написанного в том что все числа как бы параллельно разлаживаются в последовательность. Сначала все числа делим на 2. Если число делиться без остатка, то результат деления записывается на место занимаемое число в таблице. Если не делится, то просто пропускается. Если при проходе массива произошло хотя бы одно деление то текущее значение НОК умножается на 2 и текущим простым число остается 2, итерация повторяется. Если делений не было, то пора заменить текущее простое число на следующее. Если в таблице не осталось чисел больше 1 то пора выводить число HOK и прекращать обработку.
Код: Выделить всё
int table_pn [] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149};
// функция возвращает следующее простое число стоящее за переданным в параметре
int get_next_pn(int x)
{
int result = 0; // елемент не найден
for (int i = 0; i < sizeof(table_pn) / sizeof(int); i++)
{
if (x < table_pn[i])
{
result = table_pn[i];
break;
}
}
return result;
}
...
int table_a [5] = {5, 6, 13, 8, 22}; // массив чисел
int pn = 2; // стартовое простое число
int nok = 1; // инициализируем переменную под хранение НОК и именно еденицей
int a = 1; // есть что делить? 1 - да, 0 - нет (1 нужна, что бы первый раз зайти в цикл)
while (a)
{
// начинаем итерацию
a = 0; // в начале итерации считаем что массив не содержит числа которые можно поделить на простое число
int next_pn = 1; // в начале итерации считаем что неоьходимо получить следующее простое число
for (int i = 0; i < sizeof(table_a) / sizeof(int); i++) // обрабатываем каждый элемент массива
{
if (table_a[i] > 1) // проверяем, можно ли число разделить на простое число
{
if ((table_a[i] >= pn) && (table_a[i] % pn == 0.0f)) // проверяем число на деление без остатка
{
table_a[i] = (int) (table_a[i] / pn); // зарисываем результат деления в таблицу замещая число
next_pn = 0; // отмечам, что ненадо менять простое число
}
if (table_a[i] > 1)
{
// если результат в таблице все еще можно делить, то нужно отметить необходимость продолжения итераций
a = 1;
}
}
}
if (next_pn)
{
// делений в цикле не было значит пора менять простое число на большее
pn = get_next_pn(pn); // получам следующее простое число
if (!pn)
{
// если получить простое число не получилось, значит их мало в таблице и необходимо сообщить об ошибке
// nok ставим в 1 и на ввыходе программа сама будет знать что посчитать не удалось
nok = 1;
break;
}
} else
{
// иначе к текущее значение nok умножим на текущее простое число
nok *= pn;
}
}
if (nok > 1)
{
printf("NOK = %d\n", nok);
} else
{
printf("NOK ne najden!!!\n");
}
Re: Найти наименьшее общее кратное массива
Добавлено: 10 янв 2010, 13:26
Vaiper
Афигеть. Нет, я предполагал, что код будет большой, но что на столько...
Спасибо тебе огромное за помощь, попробую разобраться в этой абра-кадабре(я ведь не программист, а только учусь).Как тебя благодарить?
Re: Найти наименьшее общее кратное массива
Добавлено: 10 янв 2010, 15:41
BulldozerBSG
Ограничимся на спасибо

Я хоть и уже работаю, но учеба никогда не прекращаю, самообразование, книги, статью... Да учебу то и прекратить то не возможно, всегда найдется что то новое для изучение.
Re: Найти наименьшее общее кратное массива
Добавлено: 10 янв 2010, 15:53
Vaiper
Ну, что ж, как скажешь.

только, в коде осталась еще одна ошибочка, главна компилирует без ошибок, а запускаю выдает ошибку : undefined symbol GET_NEXT_PN(INT) in module имя_файла.cpp!
переменную задал.
И еще может ли человек изучающий СИ с сентября 2009 года сам написать такой код(вообще это лаба№1).
И можно ли связывать с тобой через личку, если что, аська или мэйл агент??
Re: Найти наименьшее общее кратное массива
Добавлено: 10 янв 2010, 21:29
BulldozerBSG
Отвечу по порядку, так много всего:
1. Еще будучи студентом научился различать понятия "помоги" и "сделай за меня". "помоги" - ничего не стоит. А "сделай за меня" - оплачивается. Большое количество помощи называется "репетиторство" и тоже оплачивается. Порою те кто приходят, путали эти понятия.
2. То что я написал в посте это куски кода реализующие алгоритм и ничего более, нет например ни includa ни функции main. И это называется "помощь". Остальное должен был сделать сам, то чего не хватает. И похоже что было это сделано не правильно. То что тебе выдало, это ошибка линкера, а не выполнения.
3. Переменную создавать не надо было, линкер ругнулся что не может найти функцию (на что указывают скобочки). Эту функцию я давал.
4. С сентября 2009 прошло чуть больше 4 месяцев. Когда я учил язык, мне хватило прочтения книги, чуть больше недели времени. Я был не хорошим студентом, поэтому вся подшивка с лабораторными работами и ргр была выполнены за 1 ночь где то перед сессией

Так что вопрос изучения, сводиться к вопросу мотивации и некоторому фундаменту знаний. ... И странно что это лабораторная №1...
5. Можно связаться ICQ (293 два девять два 587) если хочешь предложить работу будь то "напиши за меня" или "репетиторство"
Re: Найти наименьшее общее кратное массива
Добавлено: 26 авг 2010, 18:26
licenok
Код: Выделить всё
#define min(a,b) (a > b ? b : a)
int getNODab(int a, int b) // вычисляем НОД-наибольший общий делитель чмсел а и b
{
int NOD = 1;
for (int i=2; i<=min(a,b); i++)
if (a%i==0 && b%i==0) NOD = i;
return NOD;
}
int getNOKab(int a, int b) // вычисляем НОК-наименьшее общее кратное чмсел а и b
{
return a*b/getNODab(a,b);
}
Поскольку НОК(a,b,c) = НОК(НОК(a,b),c), то
Код: Выделить всё
int* mass; //массив целых чисел
int count = число элементов массива;
int NOK = 1;
for (int i=0; i<count; i++) NOK = getNOKab(NOK,mass[i]);
// и всё :)
Оптимизация алгоритма нахождения наибольшего общего делителя.
Добавлено: 27 авг 2010, 09:55
BBB
licenok ,
можно оптимизировать алгоритм ф-ии getNODab:
1) при поиске НаибОД достаточно проверять числа не от 2 до min (a,b), а от 2 до min (a,b) /2. Т.к. очевидно, что число A не может делиться нацело на число, бОльшее его половиы (бОльшее A/2)
2) не нужно перебирать ВСЕ числа от 2 до min (a,b)/2. Если перебирать не по возрастающей, а по нисходящей, то при первом же положительном результате проверке можно прерывать цикл и возвращать результат.
Вот оптимизированный вариант:
Код: Выделить всё
int getNODab(int a, int b) // вычисляем НОД-наибольший общий делитель чмсел а и b
{
int i;
for (i=min(a,b)/2; i>=2; i--)
if (a%i==0 && b%i==0) return (i);
return (1);
}