Advertisement
2andnot

Untitled

Oct 15th, 2016
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.66 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <cmath>
  4. using namespace std;
  5.  
  6. struct numExp //структура числа представленного в виде массива множетилей
  7. {
  8.     int keyArray;       //текущий индекс массива
  9.     int val;            //число из которого получился ряд простых множетилей
  10.     int keys;           //максимально вохможный индекс массива множетилей
  11.     int number[64];     //массив множетилей
  12.     int exponent[64];   //массив показателей степеня, индекс массив числа соответствует индексу массива степеней
  13. };
  14.  
  15.  
  16.  
  17. int getNextSimpNum(int val)//рекурсивная функция для нахождения простых чисел,  в качестве аргумента принимает число после которого нужно найти простое число
  18. {                          //например приняли 3 вернули 5, приняли 5 вернули 7 и так далее
  19.     val++;
  20.     while(1)
  21.     {
  22.         for(int i = 2; i < val; i++)
  23.         {
  24.             if(val%i == 0)
  25.             {
  26.                 val = getNextSimpNum(val);
  27.                 break;
  28.             }
  29.             if(i == val - 1)
  30.             {
  31.                 return val;
  32.             }
  33.         }
  34.     }
  35. }
  36. int getDividers(int val, int *temp)//функция для нахождения множетилей числа, в качестве аргумента принимает число которое нужно разложить на простые множители
  37. {                                  //и принимает адресс массива в котором эти множители нужно разместить.  возвращает количество множетилей
  38.     if(val < 2)
  39.     {
  40.         return 0;
  41.     }
  42.  
  43.     int val2 = val;
  44.     int divide = 2;
  45.     int exp;
  46.     int keyCount = -1;
  47.     //int temp[1024][2];
  48.  
  49.     while(val > 1) //раскладываем число на простые множители
  50.     {
  51.  
  52.         exp = 0;
  53.         while(!(val % divide)) //пока число делится на делитель
  54.         {
  55.             val /= divide;
  56.             exp++;
  57.         }
  58.         if(exp > 0 && keyCount < 62)
  59.         {
  60.             keyCount++;
  61.             *temp = divide;
  62.             temp++;
  63.             *temp = exp;
  64.             temp++;
  65.         }
  66.         divide = getNextSimpNum(divide);
  67.  
  68.     }
  69.     if(keyCount == -1)
  70.     {
  71.         keyCount++;
  72.         *temp = val2;
  73.         temp++;
  74.         *temp = 1;
  75.         temp++;
  76.     }
  77.     return keyCount;
  78. }
  79. void clearArray(int *temp)//очистка массива
  80. {
  81.     for(int i = 0; i < 64; i++)
  82.     {
  83.         *temp = -1;
  84.         temp++;
  85.         *temp = -1;
  86.         temp++;
  87.     }
  88. }
  89.  
  90.  
  91. int main()
  92. {
  93.     setlocale(LC_ALL, "Russian");
  94.     int numb[64][2];
  95.     clearArray(&numb[0][0]);
  96.     int key;
  97.     int c, x, z, minNum, buffer;
  98.     bool trig, trig2;
  99.     trig = trig2 = true;
  100.     numExp numberExpon[10];
  101.     buffer = 1;
  102.     cout << "Введите число ";
  103.     cin >> c;
  104.     for(x = 0; x < 10 && c > 1; x++ )
  105.     {
  106.         if( (key = getDividers(c, &numb[0][0])) >= 0 )
  107.         {
  108.             numberExpon[x].keyArray = 0;
  109.             numberExpon[x].val = c;
  110.             numberExpon[x].keys = key;
  111.             for(int i = 0; i <= key; i++)
  112.             {
  113.                 numberExpon[x].number[i] = numb[i][0];
  114.                 numberExpon[x].exponent[i] = numb[i][1];
  115.             }
  116.         }
  117.         cout << "Введите -1 для завершения или следующие число для продожения ";
  118.         cin >> c;
  119.     }
  120.     cout << "Для чисел: ";
  121.     for(int y = 0; y < x; y++)
  122.     {
  123.         cout  << numberExpon[y].val << "   ";
  124.     }
  125.     cout << endl << "наибольший общий делитель будет равен: ";
  126.     /*
  127.     Алгоритм работает по следующему принципу
  128.     Есть число которое разбито на массив простых чисел которые являются множетилями данного числа
  129.     Такие множетили сформированны в структуры(далее по программе группы)
  130.     в каждой структуре определенны поля, основные поля это массив чисел и массив степеней
  131.     принцип следующий в каждой структуре массив чисел идет упорядоченого от меньшего числа к большему
  132.     то есть например есть числа 6 и 9, изобразим ряд множителей 2, 3 и ряд множителей 3 квадрат
  133.     первая структура содержит массив чисел 2, 3 а вторая массив чисел 3 и массив степеней указывает что это квадрат
  134.     сравним первый елемент массива в структуре числа 6 и в (далее по тексту соседней) структуре числа 9
  135.     в (далее по тексту текущей)структуре числа 6 первым елементом будет число 2 которое меньше
  136.     чем первый елемент числа в соседней структуре тогда мы в текущей структуре переходим на следующий елемент массива и повторяем
  137.     сравнение числа в текущей структуре и соседней равны, если структур больше 2-х тогда соседняя становится текущей и следующая
  138.     за текущей становится соседней, повторяются те же сравнения и так до тех пор пока не будут найдены все елементы одинаковые елементы структур
  139.     после чего находится наименьший показатель степени данных чисел и производится расчет степени числа результат которого умножается на буферную переменую
  140.     затем если не достигнут был верхняя граница массива то есть еще есть числа которые могут быть одинаковы во всех структурах то поднимаемся на
  141.     следующий индекс первой структуры и производим сравнения, после чего так же множим результат возведения в степень на буферную переменную
  142.     когда же все числа будут найдены выводим результат
  143.     */
  144.     while(trig2 && trig) // до тех пор пока не отобранны все группы либо пока не пришли к границе массива множителей одной из групп
  145.     {
  146.         for(int i = 0; i<x-1; i++)//перебираем группы множетелей
  147.         {
  148.             for(; numberExpon[i].keyArray <= numberExpon[i].keys;)
  149.             {
  150.                 if(numberExpon[i].number[numberExpon[i].keyArray] > numberExpon[i+1].number[numberExpon[i+1].keyArray])//если елемент нашей группы множителей больше соседнего то переключаем следующий елемент у соседней группы
  151.                 {
  152.                     if(numberExpon[i+1].keyArray == numberExpon[i+1].keys)//если мы подошли к границам массива
  153.                     {
  154.                         i=x; // счетчик цикла становится равным границе цикла для выходя из него
  155.                         trig = false;
  156.                         break;
  157.                     }
  158.                     numberExpon[i+1].keyArray++;//увеличиваем индивидуальный ключ массива соседней группы множетилей
  159.  
  160.                 }
  161.                 else if(numberExpon[i].number[numberExpon[i].keyArray] < numberExpon[i+1].number[numberExpon[i+1].keyArray])//если елемент нашей группы множителей меньше соседнего то переключаем следующий елемент у нашей группы
  162.                 {
  163.                     if(numberExpon[i].keyArray == numberExpon[i].keys)
  164.                     {
  165.                         i=x; // счетчик цикла становится равным границе цикла для выходя из него
  166.                         trig = false;
  167.                         break;
  168.                     }
  169.                     if(i == 0)//если первое вхождение в цикле перебора групп множетилей
  170.                     {
  171.                         numberExpon[i].keyArray++;//увеличиваем индивидуальный ключ массива текущей группы множетилей
  172.                     }
  173.                     else
  174.                     {
  175.  
  176.                         numberExpon[i].keyArray++;//увеличиваем индивидуальный ключ массива текущей группы множетилей
  177.                         i = 0; //сбрасываем счетчик цикла перебора групп множетилей для повторной перегрупировки
  178.                     }
  179.  
  180.  
  181.                 }
  182.                 else
  183.                 { //если множитель текущей группы равен соседнему то пропускаем итерацию цикла для перехода к сравнению следующих групп
  184.                     break;
  185.                 }
  186.             }
  187.         }
  188.         if(trig)//если мы не дошли до границы массива какой либо из групп множетилей
  189.         {
  190.             minNum = numberExpon[0].exponent[numberExpon[0].keyArray];
  191.             for(int i = 0; i < x; i++)//ищем самый малый показатель степени множетилей
  192.             {
  193.                 if(minNum > numberExpon[i].exponent[numberExpon[i].keyArray])
  194.                 {
  195.                     minNum = numberExpon[i].exponent[numberExpon[i].keyArray];
  196.                 }
  197.             }
  198.             buffer *=  (int)(pow(numberExpon[0].number[numberExpon[0].keyArray], minNum)+0.5); //умножаем значение буффера на резудьта возведения в степень множетиля
  199.         }
  200.         if(numberExpon[0].keyArray < numberExpon[0].keys)// если массив чисел самой первой группы множетилей не достиг своей границы то переходим на следующую ячейку
  201.         {
  202.             numberExpon[0].keyArray++;
  203.         }
  204.         else //если достигли границ массива обрывам цикл
  205.         {
  206.             trig2 = false;
  207.         }
  208.     }
  209.     if(buffer > 1)
  210.     {
  211.  
  212.         cout << buffer <<endl;
  213.     }
  214.     else
  215.     {
  216.  
  217.         cout << buffer << " числа взаимно простые" << endl;
  218.     }
  219. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement