Форум программистов, компьютерный форум, киберфорум
Turbo Pascal
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.94/18: Рейтинг темы: голосов - 18, средняя оценка - 4.94
0 / 0 / 0
Регистрация: 19.04.2015
Сообщений: 6
1

Формирование одномерного массива по заданному условию внутри процедуры

19.04.2015, 13:59. Показов 3499. Ответов 13
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Задача: Функция F(x) определена с помощью ряда https://www.cyberforum.ru/cgi-bin/latex.cgi?F(x)=\sum_{n=1}^{\infty}(x^n)/(n^3).
Из заданного массива Y выделить и упорядочить по возрастанию только те элементы, для которых заданная точность вычисления https://www.cyberforum.ru/cgi-bin/latex.cgi?F(Y_i) достигается при суммировании не более M слагаемых.

Сложность возникла на моменте формирования массива из элементов исходного(Y) которые прошли через условие на количество слагаемых, пожалуйста подскажите как выполнить этот фрагмент задачи в виде процедуры, обрабатывающей входной массив переменной длинны и выдающей массив прошедших условие или как сформулировать условие так, чтобы этот этап решения был максимально рационален.

Лучший вариант который приходит в голову это сначала прогнать весь массив Y и посчитать количество элементов выходного массива, затем как-то (вероятно с помощью нетипизированнного формального параметра массива) в процедуре сформировать этот самый массив еще раз прогоняя весь Y.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.04.2015, 13:59
Ответы с готовыми решениями:

Формирование одномерного массива по условию
Тема: Формирование одномерного массива по условию. Задание: В массиве P(10) удалить все...

Формирование одномерного массива по условию
Дан массив D(10). Сформировать массив L, в который войдут модули отрицательных элементов исходного...

Формирование одномерного массива по условию
дан массив D(10). Сформировать массив L, в который войдут модули отрицательных элементов исходного...

Формирование нового массива по заданному условию
Переписать элементы целочисленного массива М (М1, М2, ... М20) кратные 5 в массив М5. Если такие...

13
Модератор
9860 / 5230 / 3304
Регистрация: 17.08.2012
Сообщений: 15,998
20.04.2015, 15:14 2
Цитата Сообщение от goblinuss Посмотреть сообщение
массив переменной длинны
В турбо паскале работа с динамическими массивами (которые переменной длины) реализуется через танцы с бубном. Может быть, Вам подойдёт статический массив с длиной, гарантированно не меньшей необходимой?
0
0 / 0 / 0
Регистрация: 19.04.2015
Сообщений: 6
20.04.2015, 22:35  [ТС] 3
Т.е. делаю формальные переменные без типа, а затем использую преобразование типа?
Кликните здесь для просмотра всего текста
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
program TR;
 
type
  mass = array [1..10] of real;
 
var
  yp, y: mass;
  eps: real;
  m, i,P: integer;
 
function sumf(e, c: real): integer;
var
  j, n: integer;
  sum: extended;
 
begin
  sum := 0.0;
  j := 1;
  while ((exp(ln(c) * j)) / (j * j * j)) >= e do
  begin
    sum := sum + (exp(ln(c) * j)) / (j * j * j);
    j := j + 1;
  end;
  sumf := j - 1;
end;
 
 
procedure fillap(var a; n, b: integer; var t: integer; var ap);
type
  mas = array[1..10000] of extended;
var
  k, i: integer;
begin
  t := 1;
  for i := 1 to n do
  begin
    if sumf(eps, mas(a)[i]) < b then
    begin
      mas(ap)[t] := mas(a)[i];
      t := t + 1
    end;
  end;
end;
 
 
 
 
procedure swapf(var ap; s: integer);
type
  mas = array[1..1000] of extended;
var
  fl: boolean;
  i: integer;
  buf: extended;
begin
  repeat
    fl := true;
    for i := 1 to s - 1 do
      if mas(ap)[i] > mas(ap)[i + 1] then
      begin
        buf := mas(ap)[i];
        mas(ap)[i] := mas(ap)[i + 1];
        mas(ap)[i + 1] := buf;
        fl := false;
      end;
  until fl;
end;
 
begin
  for i := 1 to 10 do
    readln(y[i]);
  readln(eps, m);
  fillap(y,10,m,p,yp);
  swapf(yp,p);
 for i:=1 to p do
    writeln(yp[i]);
    end.

При такой реализации у меня получается не до конца заполненный значениями массив, попадающий на обработку в другую подпрограмму, не знаю из-за этого или нет, получаю ошибку Err 205.
0
Модератор
9860 / 5230 / 3304
Регистрация: 17.08.2012
Сообщений: 15,998
21.04.2015, 00:00 4
Цитата Сообщение от goblinuss Посмотреть сообщение
получается не до конца заполненный значениями массив, попадающий на обработку в другую подпрограмму
Именно. И, к сожалению, в подпрограмму в этом случае обязательно требуется так же передавать (и использовать в ней) и размер (размеры) массива, во избежание возникновение ошибки из-за попадания в подпрограмму неинициализированных данных (ошибка 205 - это переполнение разрядной сетки при операции с плавающей точкой, наиболее распространённые - деление на 0 и вычисление ln(x) при x <= 0).

Добавлено через 1 час 8 минут
Ох, батюшки светы... Только сейчас заметил... Что это у Вас за препоганейшая реализация Вашей функции sumf? Подобные вычисления нужно делать с помощью рекуррентного соотношения, а не возводить в целочисленную степень с помощью логарифма. Ещё и "c" может быть <= 0, вот Вам и 205 из-за логарифма. Хотя бы вот так надо, безо всяких там логарифмов:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function sumf(e, c: real): integer;
var
  j: integer;
  sum, a: extended;
 
begin
  a := c;
  sum := a;
  j := 1;
  while abs(a) >= e do
    begin
      inc(j);
      a := a * c; {a^j}
      sum := sum + a / j / j / j {s + a^j / j^3}
    end;
  sumf := j
end;
1
0 / 0 / 0
Регистрация: 19.04.2015
Сообщений: 6
21.04.2015, 20:24  [ТС] 5
Добился таки нормального запуска программы, однако цикл вычисления суммы зацикливается. Воткнул перед ним оператор вывода значения C. Прога выплюнула какое-то сумасшедшее по размерам отрицательное значение, видимо передача значения идет как-то не так, не знаю как решить эту проблему.
0
Модератор
9860 / 5230 / 3304
Регистрация: 17.08.2012
Сообщений: 15,998
22.04.2015, 09:09 6
Сегодня вечером решу Вашу проблему. Скажу сразу: extended здесь не нужен, хватит и real (или, лучше, double, поскольку он во всех паскалях соответствует стандарту IEEE 754, который фактически родной для интеловских процессоров). Нетипизированные параметры процедур здесь не требуются, хватит и типизированных, а лучше применить открытые массивы. Далее. У меня есть подозрение, что в массив "y" Вы вводите что попало, а, между тем, Ваш ряд сходится на интервале [-1..1]. При вводе значений вне этого диапазона будет в лучшем случае зацикливание, а вообще - по-любому - переполнение разрядной сетки числа с плавающей точкой.
0
0 / 0 / 0
Регистрация: 19.04.2015
Сообщений: 6
22.04.2015, 14:21  [ТС] 7
Забыл сказать, что в том экземпляре кода который отправил сюда нашел ошибку, в процедуру fillap не передавались значение точности, исправил, и требование к обработке массивов произвольной длины в подзадачах и использвания для этого нетипизированных формальных параметров нам устанавлили жестко. После исправления забивал весь массив числами [0.1..1],точность задавал 0.01 и получал вышеописанный результат.
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
7769 / 4598 / 2823
Регистрация: 22.11.2013
Сообщений: 13,077
Записей в блоге: 1
23.04.2015, 08:41 8
goblinuss,
это внутри процедуры массив произвольной длины, но передают-то туда снаружи вполне определенное количество значений, с учетом уже упомянутых открытых массивов нет причин для беспокойства.

Cyborg Drone,
я бы говорил о [-1,0], поскольку 1) речь о малых, по сравнению с бесконечностью, n; 2) в этом диапазоне ряд знакопеременный убывающий, следовательно, погрешность не превысит первого отброшенного члена. Для (0,1] ряд знакопостоянный, сходится при n->бесконечности, но при малых n оценивать погрешность по значению члена знакопостоянного ряда нельзя, если правильно путаю, нужно считать предел суммы отброшенных членов.
1
Модератор
9860 / 5230 / 3304
Регистрация: 17.08.2012
Сообщений: 15,998
23.04.2015, 16:58 9
bormant, правильно. При положительном x сумма ряда при оценке величины последнего члена будет посчитана неверно. Но, в принципе, ничего страшного, погрешность получится второго порядка малости. Итак, тряхну стариной.

Возьмём предельный случай x=1. Тогда имеем ряд

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
S=\sum_{n=1}^\infty \frac{1}{n^3}<br />

Оценка остатка ряда, исходя из интегрального признака Коши:

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
\int_{z=n+1}^\infty \frac{dz}{z^3}\leq r_n\leq \int_{z=n}^\infty \frac{dz}{z^3}<br />

И тогда получается, что

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
r_n\leq \frac{1}{2n^2}<br />

Поскольку при n>1

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
\frac{1}{n^3}\leq \frac{1}{2n^2}<br />

для оценки достижения требуемой точности вычислений можно использовать сравнение погрешности с очередным членом ряда, поскольку, как правило, сумма из одного члена ряда вычисляется до цикла суммирования, а, начиная со второго члена, остаток ряда не менее очередного члена ряда. Но, если быть точным, то для x>0 для очередного члена ряда a нужно применять оценку

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
\frac{na}{2}\leq \varepsilon<br />
0
0 / 0 / 0
Регистрация: 19.04.2015
Сообщений: 6
23.04.2015, 20:58  [ТС] 10
Как в итоге заставить код работать сохранив использование преобразование типа в подзадачах?
0
Модератор
9860 / 5230 / 3304
Регистрация: 17.08.2012
Сообщений: 15,998
24.04.2015, 15:42 11
Оценка остатка ряда для положительного x вызывает затруднение. Оценка остатка ряда при 0<x≤1:

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
r_n\leq \frac{(n\ln x)^2\cdot \operatorname{Ei}(n\ln x)-x^n(n\ln x+1)}{{2n}^2}<br />

Да, конечно, можно интегральную показательную функцию разложить в ряд Тейлора:

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
\operatorname{Ei}(n\ln x)=- \int_{-n\ln x}^\infty \frac{e^{-t}}{t}dt=\gamma +\ln |n\ln x|+\sum_{k=1}^\infty \frac{(n\ln x)^k}{k\cdot k!}<br />

где γ - постоянная Эйлера, да вот беда: при больших n сходимость этого ряда мерзчайшая.

Ну и... Как будем делать критерий окончания вычислений? По-честному или как попало?
0
0 / 0 / 0
Регистрация: 19.04.2015
Сообщений: 6
24.04.2015, 20:32  [ТС] 12
Давайте как попало, честный вариант я не потяну.
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
7769 / 4598 / 2823
Регистрация: 22.11.2013
Сообщений: 13,077
Записей в блоге: 1
25.04.2015, 21:05 13
Я б как-то так делал (коррекция точности для знакопостоянного ряда все ещё требуется):
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
function ChkF(x, eps: Real; m: Integer): Boolean;
var
  e: Real; i: Integer;
begin
  ChkF:=False;
  if Abs(x)>1 then Exit;
  if x>0 then { откорректировать eps };
  e:=x; i:=1;
  while (i<=m) and (abs(e)>=eps) do begin
    Inc(i); e:=e*x/i/i/i;
  end;
  ChkF:=i<=m;
end;
 
procedure filter(
  const y: array of Real;     ny: Integer;
  var   a: array of Real; var na: Integer;
  eps: Real; m: Integer);
var
  i: Integer;
begin
  na:=0;
  for i:=0 to ny-1 do
    if ChkF(y[i],eps,m) then begin
      a[na]:=y[i]; Inc(na);
    end;
end;
 
procedure Sort(var a: array of Real; na: Integer);
  procedure swap(var a, b: Real);
  var t: Real;
  begin
    t:=a; a:=b; b:=t;
  end;
var
  i: Integer;
  done: Boolean;
begin
  repeat
    done:=True;
    for i:=0 to na-2 do
      if a[i]>a[i+1] then begin
        swap(a[i],a[i-1]); done:=False;
      end;
  until done;
end;
 
var
  y, z: array [1..100] of Real;
  eps: Real;
  m, ny, nz: Integer;
begin
  {...}
  filter(y,ny,z,nz,eps,m);
  sort(z,nz);
  {...}
end.
0
Модератор
9860 / 5230 / 3304
Регистрация: 17.08.2012
Сообщений: 15,998
25.04.2015, 22:43 14
bormant, не нужно корректировать eps. В данном случае, если x=0, то количество слагаемых считать равным 1, если нет - находить оценку остатка ряда. Для отрицательного x оценка остатка меньше, чем модуль следующего члена, для положительных я тут пошерстил немного, кое-что нашёл... Фрипаскалевская ALGLIB Free Edition библиотека: http://www.alglib.net/. Из неё можно много чего полезного взять, в том числе и Ei(x), которая там вычисляется, похоже, с помощью аппроксимации по Чебышеву. Но не получается пока, что-то я, наверное, в исчислении несобственного интеграла где-то ошибаюсь... Или вовсе с критерием Коши намудрил... Не знаю, что-то как-то не сходится ряд из остатков ряда... Буду думать, может, что и придумаю.
1
25.04.2015, 22:43
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.04.2015, 22:43
Помогаю со студенческими работами здесь

Двуменые Массивы.Формирование одномерного массива из двумерного массива по условию
1)В двумерном массиве B найти минимальный элемент среди элементов,расположенных на главной...

Сортировка элементов одномерного массива по заданному условию
Помогите пожалуста!!!!!!!! Отрицательные элементы одномерного массива расположить в порядке...

Формирование одномерного массива
Сформировать массив, преобразовав исходный массив A(N) по следующему закону : ...

Формирование одномерного массива
Помогите составить программу. Условие: Заполнить массив из N элементов с начальным значением...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru