Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.04.2012, 12:01   #1
maksimum
Пользователь
 
Регистрация: 07.04.2012
Сообщений: 21
По умолчанию Составить два массива с различными простыми числами среди элементов исходного массива и их частотами

Здравствуйте! Нужна ваша помощь. Есть такая задачка:
С клавиатуры вводятся длина одномерного массива и его элементы. Составить главную программу и подпрограмму. В главной программе ввод исходных данных, обращение к подпрограмме и вывод результатов. Все входные данные и результаты подпрограммы передаются через параметры. В подпрограмме составить два массива: с различными простыми числами среди элементов исходного массива и их частотами. Проверку на простое число оформить как функцию. Помогите найти ошибку в коде, может я что то делаю не так. В общем вот мой код:
Код:
{СОСТАВИТЬ МАССИВЫ РАЗЛИЧНЫХ ЧИСЕЛ И ЧАСТОТ 
МАССИВА А} 
USES CRT; 
TYPE TMAS=ARRAY [1..30] OF INTEGER;
VAR I,K,N,J:INTEGER; 
    A,B,C: TMAS; 
F:BOOLEAN; 
PROCEDURE FORM(VAR B,C:TMAS;
K,N: INTEGER);
I,J: INTEGER;
F:BOOLEAN;
FUNCTION PROS(B:WORD):BOOLEAN; 
{ ФУНКЦИЯ ПРОВЕРКИ ПРОСТОГО ЧИСЛА} 
VAR I:WORD; 
BEGIN 
  PROS:=B>1; 
  FOR I:=2 TO B DIV 2 DO 
    IF B MOD I = 0 THEN PROS:=FALSE; 
END; 
   K:=0; 
   FOR I:=1 TO N DO 
   BEGIN 
      F:=TRUE; 
      FOR J:=1 TO K DO 
         IF A[I] = B[J] THEN 
         BEGIN 
            F:=FALSE; 
            C[J]:=C[J]+1 
         END; 
      IF F THEN 
      BEGIN 
         K:=K+1; 
         B[K]:=A[I]; 
         C[K]:=1 
      END; 
   END; 
BEGIN CLRSCR; 
   WRITE('N='); 
   READLN(N); 
   FOR I:=1  TO N DO 
      READ(A[I]); 
  FORM(B,C,K,N);
WRITELN('  B   C'); 
   FOR I:=1 TO K DO 
      WRITELN(B[I],C[I]); 
   READKEY 
END.
maksimum вне форума Ответить с цитированием
Старый 09.04.2012, 14:53   #2
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Сразу оговорюсь, что Pascal не изучал, может там и разрешено выполнять такие действия , как у тебя, но в Delphi компилятор выдал бы ошибки.
Процедуры тоже должны иметь BEGIN END. Не увидел проверки на простое число в процедуре. Как ты передаёшь результату функции(boolean) тип WORD?
В начале функции нужно написать PROS:=TRUE; вместо PROS:=B>1;.
K:=0;
FOR J:=1 TO K DO {здесь будет ошибка, т.к. идём на понижение.}
if A[I] = B[J] then {при К=0, а соответственно и J=0 здесь будет ошибка, т.к. B[1..30], а мы полезем в B[0]}
Думаю, что будет так
Код:
PROCEDURE FORM(VAR A,B,C:TMAS;
K,N: INTEGER);
VAR
I,J: INTEGER;
F:BOOLEAN;

FUNCTION PROS(B:WORD):BOOLEAN; 
{ ФУНКЦИЯ ПРОВЕРКИ ПРОСТОГО ЧИСЛА} 
VAR I:WORD; 
BEGIN 
  PROS:=TRUE; 
  FOR I:=2 TO B DIV 2 DO 
    IF B MOD I = 0 THEN PROS:=FALSE; 
END; 

BEGIN
   K:=1; 
   FOR I:=1 TO N DO 
   BEGIN       
      IF PROS(A[I]) THEN
      BEGIN 
	F:=TRUE;
        FOR J:=1 TO K DO 
         IF A[I] = B[J] THEN 
         BEGIN 
            F:=FALSE; 
            C[J]:=C[J]+1 
         END; 
        IF F THEN 
        BEGIN 
         K:=K+1; 
         B[K]:=A[I]; 
         C[K]:=1 
        END; 
      END;
   END; 
END;
Если помог, проси поставить минус. Будь оригинален!

Последний раз редактировалось Rin; 09.04.2012 в 15:05.
Rin вне форума Ответить с цитированием
Старый 09.04.2012, 15:18   #3
maksimum
Пользователь
 
Регистрация: 07.04.2012
Сообщений: 21
По умолчанию

Спасибо большое за подсказку! Сейчас попробую так сделать. Я только начал изучать паскаль, вот с процедурами и функциями у меня проблемы.
maksimum вне форума Ответить с цитированием
Старый 09.04.2012, 15:20   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Внимание! функция проверки числа на простоту НЕКОРРЕКТНА!

рекомендую использовать такую функцию:
Код:
function isPrime(X: LongInt): boolean;
var i: integer;
Begin
     isPrime:=false;
     if x<2 then Exit;
     if not odd(x) and (x<>2) { проверяем на чётность  }
          then exit;
     i:=3;
     while i <= sqrt(x) do { проверяем только нечётные }
     begin
          if x mod i = 0 then Exit;
          inc(i,2);
     end;
     isPrime:=true;
End;

p.s. остальное в коде не смотрел...
Serge_Bliznykov вне форума Ответить с цитированием
Старый 09.04.2012, 16:00   #5
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Serge_Bliznykov,
главное, что функция работает правильно. В университете, при знакомстве с языком, нас тоже учили такому алгоритму. Предложенная Вами функция несомненно отработает быстрее, и её можно сохранить для дальнейшего использования, но думаю, что для ТС это непринципиально, ибо проверять его будет преподаватель, который сам давал ему этот алгоритм.
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Старый 09.04.2012, 16:25   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
главное, что функция работает правильно.
Да "щас"!
Точно отработает правильно?!

а ноль - это простое число? а единица?
согласно википедии (и я с ней согласен) - статья "Простые числа"
Цитата:
Последовательность простых чисел начинается так:
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, 151, 157, … (последовательность A000040 в OEIS, см. также список простых чисел)
для проверки выведите результат работы вашей "правильной" функции для 0 и для 1:
Код:
  WriteLn( PROS(0) );
  WriteLn( PROS(1) );
Это раз.

ну и второе.
ладно. хорошо. нашли Вы, что число делится без остатка (значит оно уже точно не простое), так зачем же дальше перебирать элементы в цикле?! неужели написать EXIT - это как-то усложнит функцию или сделает её менее читаемой/понятной?!!


Цитата:
но думаю, что для ТС это непринципиально, ибо проверять его будет преподаватель, который сам давал ему этот алгоритм.
вот это, безусловно аргумент!
Но от TC зависит, стоит ли написать код ЛУЧШЕ, чем тот, что ему дал преподаватель (а кстати, точно ли дал? Или TC сам это написал?! ), или удовлетвориться имеющимся кодом...
Serge_Bliznykov вне форума Ответить с цитированием
Старый 09.04.2012, 16:42   #7
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

На счёт первого уговорили безоговорочно.
На счёт второго, я сразу сказал, что Pascal не изучал, и поэтому не знаю, что чтобы выйти из процедуры пишется, именно, exit, а не halt или что-либо ещё. Поэтому и не стал писать exit. А вдруг такого в Pascal нет, и я его ввожу в заблуждение.
На счёт напутствий для ТС, согласно выводу из первого, тоже должен согласиться.
В общем вы меня уделали =).
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Старый 09.04.2012, 17:05   #8
maksimum
Пользователь
 
Регистрация: 07.04.2012
Сообщений: 21
По умолчанию

Вот что у меня получилось:
Код:
{Sostavit 2 massiva: s pazlichnimi prostimi chislami i ih chastotoj}
USES CRT; 
TYPE TMAS=ARRAY [1..30] OF INTEGER;
VAR I,K,N,J:INTEGER; 
    A,B,C: TMAS; 
F:BOOLEAN; 
PROCEDURE FORM(VAR A,B,C:TMAS;
K,N: INTEGER);
VAR
I,J: INTEGER;
F:BOOLEAN;

FUNCTION PROS(B:WORD):BOOLEAN; 
{Funkcia na opredelenie prostogo chisla}
VAR I:WORD; 
BEGIN 
  PROS:=TRUE; 
  FOR I:=2 TO B DIV 2 DO 
    IF B MOD I = 0 THEN PROS:=FALSE; 
END;

BEGIN
   K:=1; 
   FOR I:=1 TO N DO 
   BEGIN       
      IF PROS(A[I]) THEN
      BEGIN 
	F:=TRUE;
        FOR J:=1 TO K DO 
         IF A[I] = B[J] THEN 
         BEGIN 
            F:=FALSE; 
            C[J]:=C[J]+1 
         END; 
        IF F THEN 
        BEGIN 
         K:=K+1; 
         B[K]:=A[I]; 
         C[K]:=1 
        END; 
      END;
   END; 
END;
BEGIN CLRSCR;
   WRITE('N=');
   READLN(N); 
   FOR I:=1  TO N DO 
      READ(A[I]); 
FORM(A,B,C,K,N);
  WRITELN ('Prostie chisla:');
  FOR I:=1 TO N DO
      WRITE(B[I]:3);
      WRITELN ('Chastota prostih chisel:');
      FOR I:=1 TO N DO
      WRITE(C[I]:3);
   READKEY
END.
Вот только K не считается, а если использовать N, то вместо тех чисел которые не удовлетворяют условию выводит нули.
По поводу простого числа, попробую и такой вариант. Всем спасибо за помощь!
maksimum вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
массиве X(N) найти максимальный элемент среди положительных элементов массива и минимальный среди отрицательных элементов. sorok Общие вопросы C/C++ 2 20.03.2012 12:18
Турбо ассемблер - построить массив путём сдвига исходного массива и умножить все элементы полученного массива на два Александр16 Помощь студентам 5 12.02.2012 20:30
Турбо ассемблер - построить массив путём сдвига исходного массива и умножить все элементы полученного массива на два Александр16 Помощь студентам 1 12.02.2012 19:56
Из исходного массива заполнить два других массива DarkStalkerus Паскаль, Turbo Pascal, PascalABC.NET 1 14.12.2011 14:19
Pascal: Составить программу генерирования массива B, состящего из отрицательных элементов массива a mrRastom Помощь студентам 2 15.01.2011 14:33