Страница 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); 
}