Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ элементы массива

Автор: лоен 19.01.2008 20:18

а собственно как удалять и дублировать элементы массива? unsure.gif

Автор: мисс_граффити 19.01.2008 20:25

как массив описан? динамический, статический - какой?
в такой формулировке ответить невозможно.

Автор: лоен 19.01.2008 20:39

ок, статический, например

const Nmax=10000;
var n,i: integer;
a:array [1..Nmax] of integer;
begin
Writeln('Vvedite dliny posledovatelnosti(n<=10000)');
Readln(n);
Writeln('Vvedite posledovatelnost');
For i:=1 to n Do Begin
Readln(A[i]);
{и если элементы подходят какому-то условию, то например удаляем}
end;
For i:=1 to n Do WriteLn(A[i]);
Readln;
end.

Автор: Client 19.01.2008 20:47

for j:= i to n-1 do a[j]:=a[j+1]

Автор: volvo 19.01.2008 21:02

Так будет гораздо быстрее:

  move(a[j + 1], a[j], (n - j)*sizeof(a[j])); { удаляем J-ый элемент }


Автор: Client 19.01.2008 21:11

(n - j)*sizeof(a[j])
А можно пояснение?
Как я понял, move это процедура, в которой 1-й параметр заменит 2-й, а вот 3-й параметр-сколько раз это повторить?

Автор: volvo 19.01.2008 21:22

Не совсем... Это процедура, которая с адреса задаваемого первым параметром переносит число байт, заданных третьим параметром в другое место, адрес которого задан вторым параметром...

Чем удобнее: тебе не надо волноваться, какой цикл поставить, по возрастанию или по убыванию, Move прекрасно справляется с этим сама:

{
Пример: тебе надо вставить еще один элемент после J-го,
то есть сдвинуть все элементы начиная с J+1-го вправо
}
for i := j to n - 1 do a[i + 1] := a[i]; { <--- Это - ошибка }
for i := n - 1 downto j do a[i + 1] := a[i]; { <--- Вот так будет правильно }

Процедура Move тебя от таких ошибок избавляет, она сама правильно выбирает направление копирования...

Автор: Client 19.01.2008 21:55

А как на этом примере удалить 2-й элемент(-2-й элемент)?

uses crt;
var
a:array [-3..3] of integer;
i,j:integer;
begin
clrscr;
for i:=-3 to 3 do readln(a[i]);
// вот здесь не знаю как ее вызвать, в цикле или нет...
for i:=-3 to 3 do write(a[i]);
readkey
end.

Теперь понял. Сделал так
for i:=-2 to 2 do move(a[i + 1], a[i], sizeof(a[i]));
А если сделать цикл до 3-х, то почему последний элемент стал 3, если ввести 1 2 3 4 5 6 7?

Автор: volvo 19.01.2008 22:21

Ну, и в чем здесь сложность?

uses crt;
const
a: array [-3..3] of integer =
(1, 2, 3, 4, 5, 6, 7);

var
i,j:integer;
to_delete: integer;
begin
clrscr;
to_delete := 2; { <--- Чтобы удалить -2 достаточно просто поменять это значение }
move(a[to_delete + 1], a[to_delete],
(high(a) - to_delete)*sizeof(a[to_delete]));
for i:=-3 to 3 do write(a[i]:3);
readln;
end.



Добавлено через 1 мин.
Блин... Да не надо никаких циклов... Move для того и придумали, чтобы от циклов избавиться!!!

Автор: Client 19.01.2008 22:43

Цитата
Блин... Да не надо никаких циклов... Move для того и придумали, чтобы от циклов избавиться!!!
Мда, накосячил я...
А что такое sizeof? И почему
move(a[to_delete + 1], a[to_delete], (high(a) - to_delete)*sizeof(a[to_delete]));
и
move(a[to_delete + 1], a[to_delete],sizeof(a));
отработали одинаково?

Автор: volvo 19.01.2008 23:19

Цитата
отработали одинаково?
Ну, допустим, отработали они совсем не одинаково, во втором случае ты залез в области памяти, занятой другой переменной, просто не видишь этого (а компилятор тебе это не показывает). Нужно копировать столько элементов, сколько осталось с to_delete до конца массива, а размер каждого элемента в байтах - это sizeof(a[какой_нибудь_индекс])...

Автор: Client 19.01.2008 23:24

То-то он мне вывел sizeof(a)=14
Теперь все понял
БОЛЬШОЕ СПАСИБО good.gif

Автор: feniks25 19.01.2008 23:26

Цитата(volvo @ 19.01.2008 18:19) *

а компилятор тебе это не показывает

Кстати, смех, код протестировал на делфях. Хотел, чтобы ругнулось, а оно отработало и не заметило

1234567
1234674221616

Автор: volvo 20.01.2008 0:37

Цитата
Хотел, чтобы ругнулось
Читал бы доки внимательно - перестал бы хотеть:
Цитата(D2007 Help)
Description
Move copies Count bytes from Source to Dest. No range checking is performed. Move compensates for overlaps between the source and destination blocks.
Вся ответственность за нарушение границ при использовании Move ложится на программиста. Вот, смотри, здесь явно видно, что происходит "переход" границы массива:
var
i,j:integer;
add_after: integer;
a: array [-3..3] of integer =
(1, 2, 3, 4, 5, 6, 7);
b: array[1 .. 5] of integer =
(0, 0, 0, 0, 0);
begin
add_after := 1;
move(a[add_after], a[add_after + 1], sizeof(a));
for i:=-3 to 3 do write(a[i]:3);
writeln;

for i := 1 to 5 do write(b[i]:3);
readln;
end.

Чему равен первый элемент b?

Автор: лоен 20.01.2008 1:17

гм, а дублировать?

Автор: Client 20.01.2008 1:28

Цитата
гм, а дублировать?
Поточнее скажи, что дублировать. Пример напиши

Автор: лоен 20.01.2008 1:37

ну допустим из соседнего топика)
среди оставшихся чисел нужно продублировать простые

const Nmax=10000;
var
n, i, s, b, j: integer;
a: array[1 .. Nmax] of integer;

begin
Writeln('Vvedite dliny posledovatelnosti(n<=10000)');
Readln(n);
Writeln('Vvedite posledovatelnost');
for i := 1 to n do Readln(A[i]);
i := 1;
while i <= n do begin
s := 0;
b := A[i];
while b > 0 do begin
S := s + (b mod 10);
b := b div 10;
end;
if (s mod 8) = 0 then begin
n := n - 1;
for j := i to n do a[j]:=a[j+1];
end;
inc(i);
end;
for i :=1 to n Do Write(A[i],' ');
Readln;
end.

Автор: Client 20.01.2008 1:52

Проверяешь число, простое ли оно, если да, то пользуешься процедурой move