nixp.ru v3.0

23 января 2017,
понедельник,
03:39:04 MSK

DevOps с компанией «Флант»
anonymous написал 2 марта 2004 года в 17:47 (358 просмотров) Ведет себя неопределенно; открыл 1814 темы в форуме, оставил 5575 комментариев на сайте.

Помогите плиз написать прогу на паскале ну или хоть алгоритм?

Задан массив натуральных чисел. Упорядочить элементы массива по возрастанию количества кратных простых делителей. (Кратные простые делители это те которые делятся на 1 и сами на себя).

Longobard

Ну и в чем проблема? Я бы поступил так (решение в лоб, думать некогда, возможно можно и порациональнее). Берем дом. массив с эл-ми типа byteи и кол-вом эл-в равном кол-ву чисел в первом массиве. Пусть массив с числами — массив x[1..n] of longint; . И массив y[1..n] of byte.

Берем очередной эл-т из массива x. Считаем ЕГО кол-во простых кратных делителей. Записываем это количество в элемент массива y с таким же номером. Т.е.

for i := 1 to n do
   y[i] := Кол-во_простых_кратных_делителей (x[i]);

Теперь берем и сортируем массив y и ОДНОВРЕМЕННО с ним и массив x. То есть когда переставляем местами эл-ты массива y то переставляем соответствующие эл-ты массива x. Получаем необходимый массив x. Можно также сделать по другому. Можно сделать массив структур, где одно поле-число, а другое — его кол-во кратных простых делителей. Далее упорядочиваем точно так же. Но массив один.

Ну посчитать кол-во простых кратных делителей просто: перебираешь делители (от 1 до num div 2), и проверяешь их на кратность и простоту. Я это делал еще в 9-м классе. Если будет время — напишу тебе эту программулечку. Ну а вообще эта задача элементаран, я не понимаю где тут могут возникнуть проблемы.

Negative

LONGOBARD, а не в лом было отвечать?

anonymous

Потому и хочется поинтереснее, что задачка тривиальная (раз уж взялись двоечникам домашнее задание делать :-)). Как по поводу следующего алгоритма? Тасуем карты.

1. Находим максимальный элемент массива, М.

2. Извлекаем квадратный корень из M, берем его целую часть и прибавляем 1, получаем К.

3. Для каждого простого числа p меньше или равного K делаем вот что:

Проходим массив задом наперед;

Если текущий элемент массива делится на p, кидаем его в самый конец массива, хвост массива сдвигаем.

4. После того, как все простые числа перебраны, массив упорядочен по числу простых делителей.

Не знаю, будет ли это работать, но выглядит забавно…

Good Luck,

UT

Longobard

Ээээ… Можно проверить, а не мог бы ты пояснить по какому алгоритму ты это решал? Просто мне интересно. А чувак щас походу дела офигеет, тут такие разговоры пойдут… Троечную задачку будут решать с помощью какого-нибудь алгоритма из комбинаторики или дискретного анализа :) Он подумает » а может нах его, этот кодинг? Если такие задачи решаются с помощью таких вещей, то что будет дальше». В результате совместных усилий всех кодеров никспа и UT в качестве супермозга будет выработана прога линой не менее 200 строк и использующая алгоритмы [censured] :)

anonymous

Резвился это я… Не, не будет работать. Два раза я сглупил, Во-первых, простой делитель не обязян быть меньше чем корень из числа, а во-вторых, у кого самый большой простой делитель, тот и окажется в конце списка. А вовсе не тот, у кого больше простых делителей.

Ну и фиг с ним. :-)

Good Luck,

UT

decvar

Сильно…….внушает……

anonymous

Вобчем я ее набил но все равно где то ошибка он 0 вместо упорядоченного массива выводит:

Program ind1;

Const N=5;

Var

r,nmax,k,i:byte; c:integer;

b : array [1..N] of integer;

a : array [1..N] of integer;

Function kr (x:integer):integer;

Var i,k,m,l,kv : byte;

a : array [1..100] of integer;

Begin k:=0; kv:=0;

For i:=2 to N div 2 do Begin

m:=N mod i;

If m=0 then begin

k:=k+1;

a[k]:=i; l:=0;

While m=0 do Begin

X:=X div i; m:=X mod i; l:=l+1;

End;End;

if l>1 then kv:=kv+1;

kr:=a[k];

End;

End;

Begin

Writeln;

Write (’Vvedite massiv iz ',n,' elementov: ');

For i:=1 to n do Begin

Read (b);

b:=kr(a);

End;

For k:=n downto 2 do Begin

For i:=2 to k do Begin

if b[nmax]

<b then="» nmax:=«i;»>c:=b[nmax]; b[nmax]:=b[k]; b[k]:=c;</b>

<b then="» nmax:=«i;»>c:=a[nmax]; a[nmax]:=a[k]; a[k]:=c; End;</b>

<b then="» nmax:=«i;»>For i:=1 to i do Write (a[k],' ');</b>

<b then="» nmax:=«i;»>End.</b>

Longobard

Ты слышал про написание ЧИТАБЕЛЬНОГО кода? Такие слова как отступы и инетрвалы тебе знакомы? Перепиши по нормальному, тогда и посмотрим.

Xaos

Сорри!?

Program ind1;

Const N=5;

Var

r, nmax, k, i : byte;

                 c : integer;

                 b : array [1..N] of integer;

                 a : array [1..N] of integer;

Function kr (x : integer) : integer;

Var i, k, m, l, kv : byte;

                       a : array [1..100] of integer;

Begin

k:=0; kv:=0;

For i:=2 to N div 2 do Begin

                                     m:=N mod i;

                                     If m=0 then begin

                                                          k:=k+1;

                                                          a[k]:=i; l:=0;

                                                          While m=0 do Begin

                                                                                    X:=X div i;

                                                                                    m:=X mod i;

                                                                                    l:=l+1;

                                                                                    End;

                                                          End;

if l>1 then kv:=kv+1;

kr:=a[k];

                                    End;

End;

Begin

Writeln;

Write (’Vvedite massiv iz ',n,' elementov: ');

For i:=1 to n do Begin

                           Read (b);

                           b:=kr(a);

                           End;

For k:=n downto 2 do Begin

                                      For i:=2 to k do Begin

                                                                  If b[nmax]

<b then="» nmax:=«i;»>                                                                  end;</b>

<b then="» nmax:=«i;»>                                      c:=b[nmax]; b[nmax]:=b[k]; b[k]:=c;</b>

<b then="» nmax:=«i;»>                                      c:=a[nmax]; a[nmax]:=a[k]; a[k]:=c;</b>

<b then="» nmax:=«i;»>                                      End;</b>

<b then="» nmax:=«i;»>For i:=1 to i do Write (a[k],' ');</b>

<b then="» nmax:=«i;»>End.</b>

Longobard

Влом врубацца, но изначально неверно. Ты сначала читвешь массив. Полностью. Затем считаешь простые делители и заполняешь таким раком массив b. А у тебя так:

For i:=1 to n do Begin  
                            Read (b[i]);  
                            b[i]:=kr(a[i]);

не понял! Ты читаешь элемент массива и сразу его портишь. А портить его нельзя, надо посчитать кол-во делитеолей и запихать это в a;. И почему отсчет идет во всех циклах от 2 а не от 1? Короче переписывай по нормальному, а еще лучше посиди и подумай сам. Порисуй на бумажке ход твоего алгоритма, пойми где глюк. Если ты не сможешь решить и такую задачку — то ИМХО бросай ты кодинг. Ничего у тебя путного все равно не выйдет в таком случае.

anonymous

И ведь правда ж Паскаль! Умереть и не встать. С надо изучать, а не это несчастье. Ну ладно, что бросается в глаза.

Program ind1;

Const N=5;

Var

r, nmax, k, i : byte;

c : integer;

b : array [1..N] of integer;

a : array [1..N] of integer;

Function kr (x : integer) : integer;

Var i, k, m, l, kv : byte;

a : array [1..100] of integer;

Begin

k:=0; kv:=0;

For i:=2 to N div 2 do Begin

m:=N mod i;

If m=0 then begin // i делит N, OK

//Если N == 5 как у тебя, дальнейшее пропускается

k:=k+1;

a[k]:=i; l:=0;

While m=0 do Begin

X:=X div i;

m:=X mod i;

l:=l+1;

End;

End;

//до этого места

if l>1 then kv:=kv+1; // l не инициализирована, Паскаль, кажется,

// считает ее нулем

kr:=a[k]; // k == 0, a[k] == 0 по той же причине

End;

End;

/* Здесь кончается функция и начинается тело программы, так?*/

Begin

Writeln;

Write (’Vvedite massiv iz ',n,' elementov: ');

For i:=1 to n do Begin

Read (b);

b:=kr(a); //a[] модифицируется в kr

End;

For k:=n downto 2 do Begin

For i:=2 to k do Begin

If b[nmax]

<b then="» nmax:=«i;»>end;</b>

<b then="» nmax:=«i;»>c:=b[nmax]; b[nmax]:=b[k]; b[k]:=c;</b>

<b then="» nmax:=«i;»>c:=a[nmax]; a[nmax]:=a[k]; a[k]:=c;</b>

<b then="» nmax:=«i;»>End;</b>

<b then="» nmax:=«i;»>For i:=1 to i do Write (a[k],' ');</b>

<b then="» nmax:=«i;»>/*************************************************************/</b>

<b then="» nmax:=«i;»>Ладно, слушай. Вот тебе идея, как программу такую писать.</b>

<b then="» nmax:=«i;»>1. Решаем, что делать.</b>

<b then="» nmax:=«i;»>а) Читаем массив nubers[]:</b>

<b then="» nmax:=«i;»>б) Для каждого элемента определяем число его простых делителей</b>

<b then="» nmax:=«i;»>— это в функцию:</b>

<b then="» nmax:=«i;»>в) Загоняем это число в другой массив primes[];</b>

<b then="» nmax:=«i;»>г) Упорядочиваем numbers[] по primes[] — это процедурой.</b>

<b then="» nmax:=«i;»>д) Выводим numbers[].</b>

<b then="» nmax:=«i;»>Решили. У нас будет:</b>

<b then="» nmax:=«i;»>int NumberOfPrimes(int num);</b>

<b then="» nmax:=«i;»>void OrderArray(int * numberArray, int * primeArray);</b>

<b then="» nmax:=«i;»>int main()</b>

<b then="» nmax:=«i;»>{</b>

<b then="» nmax:=«i;»>const int N; //dimension</b>

<b then="» nmax:=«i;»>int numbers[N], int primes[N];</b>

<b then="» nmax:=«i;»>for(int i=0;i</b>

<b then="» nmax:=«i;»>cin >> numbers; //прочитали</b>

<b then="» nmax:=«i;»>for(int i=0;i</b>

<b then="» nmax:=«i;»>primes = NumberOfPrimes(numbers); //посчитали</b>

<b then="» nmax:=«i;»>OrderArray(numbers, primes); //упорядочили</b>

<b then="» nmax:=«i;»>for(int i=0;i</b>

<b then="» nmax:=«i;»>cout << numbers << » »;</b>

<b then="» nmax:=«i;»>cout << endl;// вывели</b>

<b then="» nmax:=«i;»>return 0;</b>

<b then="» nmax:=«i;»>}</b>

<b then="» nmax:=«i;»>2. Пишем функцию и процедуру. Опять решаем, как мы будем определять количество простых делителей числа x. Если не ударяться в изыски, перебираем все целые меньше x. Если ни на одно из них x не делится, объявляем его простым. Т.е. еще функция</b>

<b then="» nmax:=«i;»>bool isAprime(int x)</b>

<b then="» nmax:=«i;»>{</b>

<b then="» nmax:=«i;»>bool result = true; // презумпция невиновности :-)</b>

<b then="» nmax:=«i;»>for(int i=2;i</b>

<b then="» nmax:=«i;»>if(x % i == 0)</b>

<b then="» nmax:=«i;»>result = false;</b>

<b then="» nmax:=«i;»>return result;</b>

<b then="» nmax:=«i;»>}</b>

<b then="» nmax:=«i;»>Теперь пишем</b>

<b then="» nmax:=«i;»>int NumberOfPrimes(int x)</b>

<b then="» nmax:=«i;»>{</b>

<b then="» nmax:=«i;»>int result = 0;</b>

<b then="» nmax:=«i;»>for(int i=2;i</b>

<b then="» nmax:=«i;»>if(isAprime(i) && x % i == 0) //если i простое и делит x</b>

<b then="» nmax:=«i;»>result++;</b>

<b then="» nmax:=«i;»>return result;</b>

<b then="» nmax:=«i;»>};</b>

<b then="» nmax:=«i;»>Как мы будем упорядочивать массив? Найдем максимальный элемент и запишем его в самый конец. На следующем шаге упорядочим массив на один элемент короче.</b>

<b then="» nmax:=«i;»>void OrderArray(int * numberArray, int * primesArray) //в Паскале это будет</b>

<b then="» nmax:=«i;»>//процедура</b>

<b then="» nmax:=«i;»>{</b>

<b then="» nmax:=«i;»>int currentMax = -1, currentNumber = -1, placeOfMax = -1;</b>

<b then="» nmax:=«i;»>for(j=1;j</b>

<b then="» nmax:=«i;»>{</b>

<b then="» nmax:=«i;»>for(int i=0;i</b>

<b then="» nmax:=«i;»>if(primesArray > currentMax)</b>

<b then="» nmax:=«i;»>{</b>

<b then="» nmax:=«i;»>placeOfMax = i;</b>

<b then="» nmax:=«i;»>currentMax = primesArray;</b>

<b then="» nmax:=«i;»>};</b>

<b then="» nmax:=«i;»>currentNumber = numberArray[placeOfMax]</b>

<b then="» nmax:=«i;»>//Нашли макс. элемент. Переставляем в конец</b>

<b then="» nmax:=«i;»>primesArray[placeOfmax] = primesArray[N-j];</b>

<b then="» nmax:=«i;»>numberArray[placeOfMax] = numberArray[N-j];</b>

<b then="» nmax:=«i;»>primesArray[N-j] = currentMax;</b>

<b then="» nmax:=«i;»>numberArray[N-j] = numberMax;</b>

<b then="» nmax:=«i;»>currentMax = -1;</b>

<b then="» nmax:=«i;»>currentNumber = -1;</b>

<b then="» nmax:=«i;»>placeOfMax = -1;</b>

<b then="» nmax:=«i;»>}; // конец верхнего цикла</b>

<b then="» nmax:=«i;»>};</b>

<b then="» nmax:=«i;»>Усе!! Уфф!!! Сорри, что пишу на C, но что-то ж и тебе надо сделать. Пиши максимально модульно. Разбивай задачу сверху вниз, называй переменные, чтобы было понятно, для чего они используются и пиши больше комментариев. И все будет!</b>

<b then="» nmax:=«i;»>А потом можно еще долго это дело оптимизировать, дебаггить и т.д. :-)</b>

<b then="» nmax:=«i;»>Good Luck,</b>

<b then="» nmax:=«i;»>UT</b>

anonymous

По поводу Паскаля. Кто-нибудь знает объективную причину в том, что у нас так популярен Паскаль (ну и Делфи как следствие), кроме как то что на основе его нам преподают программирование? Главное, что хотят нам дать только принципы программирования, а не сам язык (который и создан был для обучения). А в итоге получаем, что люди используют его всегда и везде.

Uncle Theodore
bool isAprime(int x)

{

bool result = true; // презумпция невиновности :-)

for(int i=2;i

   if(x % i == 0)

     result = false;

return result;

}

Немного неоптимально каждый раз прощитывать является ли число простым или нет — в цикле получать остаток от деления. Я бы сделал прекалькулейт — сформировать массив из простых чисел от 1 до максимального числа из заданного массива. И сделать это без участия операций деления — как на бумажке — путем вычеркивания:

а) 1 — простое число

б) берем след. невычеркнутое число «к» (на первой итерации это «2») и вычеркиваем до конца массива каждое «к»-ое число (для «к»==2 это — 4,6,8..).

Когда очередное «к» — вне границы массива, то все «непростые» числа вычеркнуты

anonymous

1 — не простое число :-)

Паскаль, видимо, когда-то был «утвержден» инстанциями как самый наш язык программирования. Ладно, хоть не Бейсик.. :-)

Здесь можно до фига чего оптимизировать. Например, ту же

bool isAprime(in) лучше писать как

bool isAprime(int x)

{

for(int i=2;i

if(x % i == 0)

return true;

return false;

}

Я хотел, в основном дать товарищчу идею, как правильно писать прогу. Там даже несколько ошибок есть. Может, посчитать заранее простые числа и быстрее, хотя — надо знать максимальный элемент массива, и перебирать по массиву тоже не быстро, разве что бинарно. Но тогда код просечь будет трудно, и чел ни фига не поймет за наворотами. :-)

А вообще, не нак уж и плохо он написал. Плохо, что он не умеет искать ошибки, и писать код так, чтобы ошибки легче отлавливались. Но это придет.

Good Luck,

UT

Genie

Ага, как зададим, блин, простое число чуть меньше 2^31, так и будет программка считать до посинения число его делителей…

Есть у меня такая. Ищущая все 32-битные простые числа и складывающая их в фалик (числа в десятичной нотации, текстом). Работает ооочень долго (около 8 часов на Cel-1.4 [tualatin]).. Хотя основной цикл — строчек 30 на асме… И не сказать бы, что алгоритм неоптимальный, оптимальнее альтернативного решета Эратосфена ещё ничего не обнаружено.. (точнее можно сделать, но, блин, памяти будет требовать в два раза больше….)

ecobeingecobeing.ru
Экология и вегетарианство на благо всем живым существам Планеты.