2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Pascale.Проблема с массивами...
Сообщение05.01.2008, 18:03 
Проблема с задачей:
2.Пусть А-одномерный массив N целых чисел
а)Поменять местами макс. по модулю элемент и элемент ближащий к числу 1.87
б)Проверить является ли 6-ой чётный элемент полож.,а если такого элемента нет вывести сообщение
в)Искл.из массива все нулевые элементы


есть решение подобной задачи задачи...:
Код:
        Program 64;
uses crt;
var
a                :array [1..100] of real;
b                :array [1..100] of real;
i,j,ch,ch1       :integer;
min,max,change   :real;
Begin
randomize;
clrscr;
For i:=1 to 10 do
  begin
   a[i]:=random(50)/7-3;
   write('  ',a[i]:3:2);
  end;
writeln;
max:=a[1];
For i:=1 to 10 do
  begin
   if max<a[i] then
    begin
     max:=a[i];
     ch1:=i;
    end;
   if (a[i])>=0 then b[i]:=a[i]+2.75;
   if (a[i])<0 then b[i]:=abs(a[i])-2.75;
  end;
min:=abs(b[1]);
For i:=1 to 10 do
  if min>abs(b[i]) then
   begin
    min:=abs(b[i]);
    ch:=i;
   end;
writeln;
writeln('max=',max:5:2);
writeln('blij=',a[ch]:5:2);
if (a[4]>=0) then writeln('4-bIu element polojitelnij');
change:=a[ch];
a[ch]:=a[ch1];
a[ch1]:=change;
writeln;
For i:=1 to 10 do write('  ',a[i]:3:2);
Readkey;
end.



Вот так она выглядит:
Изображение


Помогите пожалуйста решить выше указанную задачу!

 
 
 
 
Сообщение06.01.2008, 03:43 
Аватара пользователя
:evil:
Вы, конечно, правы: похожая программа может помочь. Помочь Вам. Нам помощь не очень нужна: такого сорта программа пишется минут за 10, включая отладку. Но чему Вас научит то, что мы напишем за Вас программу? Ничему. Вот мы и не будем писать.

Если хотите, напишите свою программу, и поместите её на форуме. Вот тогда мы и будеи говорить.

P.S. Кстати, умение читать чкжие программы — очень полезно. Так что Вам повезло, что у Вас есть, что почитать

 
 
 
 
Сообщение07.01.2008, 22:05 
ну собственно говоря со 2 пунктом не получается...
Код:
program xxx;
uses crt;
const n=20;
Type MyAr=Array [1..n] of integer;
var a:myar;
sav,i,k,max1,max2,x,z,v:integer;
begin
       clrscr;
       randomize;
       max1:=-100;
       max2:=-100;
    for i:=1 to n do
     begin
       a[i]:=random (110);
       a[i]:=a[i]-50;
         if a [i] > max1 then
           begin
             max1:=a[i];
             z:=i;
           end;
         if (a[i]-18.7) > max2 then
            begin
              max2:=a[i];
               x:=i;
            end;

        write (a[i]:5);
     end;
             writeln;
             writeln('maximal element massiva Max1=',max1);
             writeln('6lij element massiva k 1.87=',max2);
             sav:=a[z];
             a[z]:=a[x];
             a[x]:=sav;
             v:=0;
             z:=0;
             x:=0;
             for i:=1 to n do
    begin
        write (a[i]:5);
             if((a[i] mod 6)=0) then
    begin
             z:=i;
             v:=v+1;
           end;
             if(v=6) and (a[z]>0) then x:=1
           end;
             writeln;
             if x=1 then writeln('6-i chet element polojit');
             v:=0;
             for i:=1 to n do
    begin
             if a[i]<=0 then
    begin
             v:=v+1;
             a[v]:=a[i];
           end;
             for i:=1 to n do
             write(a[i]:5);
             readln;

    end;

     k:=0;
   for i:=1 to n do
      begin
       if  a[i] mod 2 = 0 then k:=k+1;
         if k=6 then
            begin
             if a[i] >0  then   writeln(a[i],'>0')
              else writeln('a[i]<0');
              k:=7 ;
            end;

      end;
                if k<4 then writeln ('net 4etnogo polosjitelnigi 6 elementa!');
    readln;

           end.

 
 
 
 
Сообщение07.01.2008, 23:40 
Аватара пользователя
:evil:
xpom писал(а):
Код:
01k:=0;
02   for i:=1 to n do
03      begin
04       if  a[i] mod 2 = 0 then k:=k+1;
05         if k=6 then
06            begin
07             if a[i] >0  then   writeln(a[i],'>0')
08              else writeln('a[i]<0');
09              k:=7 ;
10            end;
11
12      end;
13                if k<4 then writeln ('net 4etnogo polosjitelnigi 6 elementa!');


Я вижу две ошибки:

1) Мне не очень понятно, почему число чётных ($k$) сравнивается с 4 (строка 13)

2) То, что не положительно, не значит, что оно отрицательно. Отсюда ошибка в строке 8.

В качестве непрошенных советов:

1) не ленитесь писать begin-end. Хотя это синтаксически не обязательно, Вы не поверите, сколько часов потрачено, чтобы найти ошибки, связанные с этим.

2) Вообще говоря, лучше проверять, что $k = 6$ внутри условного оператора, находящего чётное число, а не при каждом исполнении цикла. Примерно так:

Код:
01  k:=0;
02  for i:=1 to n do
03  begin
04    if  a[i] mod 2 = 0 then
05    begin
06      k:=k+1;
07      if k=6 then
08      begin
09        if a[i] >0  then   writeln(a[i],'>0')
10        else writeln('a[i]<0');
11      end;
12    end;
13  end;

То есть, проверка исполняется лишь на чётных элементах массива. Кроме того, обратите внимание, что строка 9 (из старого текста) стала не нужна.

3) Может быть, имеет смысл переписать этот код, используя цикл while, c тем, чтобы не продолжать просмотр массива после нахождения 6-го чётного.

 
 
 
 
Сообщение08.01.2008, 04:36 
незваный гость писал(а):
1) не ленитесь писать begin-end. Хотя это синтаксически не обязательно, Вы не поверите, сколько часов потрачено, чтобы найти ошибки, связанные с этим.

Вы не поверите, но есть преподаватели, которые заставляют не писать "лишние" begin-end. Например, мой преподаватель не принял у меня лабораторные, пока я не убрал begin-end там где они строго не требуются. Я сам был в шоке.

 
 
 
 
Сообщение08.01.2008, 07:59 
Аватара пользователя
:evil:
Отчего же, поверю. Есть разные игры, например, в «зачёт», и в «жизнь». Преподаватель может требовать всего, что угодно, в частности, требования знания синтаксиса языка, что вовсе не возбраняется. Вполне резонным вопросом преподавателя является «А зачем Вы написали это begin - end?» Не знаете — незачёт. И, как ни странно, я согласен с ним. В некотором смысле, привычка писать begin-end приходит обычно с опытом, которого у большинства студентов нет. А задача преподавателя — научить. В некотором смысле неосознаное использование этих скобок сродни тому, что треугольник — это всегда ${\scriptstyle \triangle}ABC$, и применить теорему косинусов к ${\scriptstyle \triangle}PQS$ учащийся не в состоянии.

Не говорить об этом? Не знаю… По-моему, тоже глупо. Хотя бы потому, что я выучил матан, а не изобретал его. Да, я понял каждую теорему, но не изобрёл её. Так и здесь: можно понимать, зачем это делается, не обязательно изобретая трюк.

 
 
 
 
Сообщение09.01.2008, 02:14 
xpom писал(а):
Код:
sav:=a[z];
a[z]:=a[x];
a[x]:=sav;


Почему бы не написать так, экономя на переменной sav:
Код:
a[x]:=a[x]-a[z];
a[z]:=a[x]+a[z];
a[x]:=a[z]-a[x];


Почему бы не написать так? :-)

 
 
 
 
Сообщение09.01.2008, 03:16 
luitzen писал(а):
Почему бы не написать так? :-)

Такого типа алгоритм существует для беззнаковых целых с использованием операции xor (^):
Код:
a[x] := a[x] xor a[z];
a[z] := a[x] xor a[z];
a[x] := a[z] xor a[x];

Вариант с арифметикой (+ и -) может дать ошибку при некоторых исходных данных. Например, если a[x] равно максимальному положительному числу ($7FFFFFFF для 32-бит) и a[z]:= -2

 
 
 
 
Сообщение09.01.2008, 08:07 
Аватара пользователя
:evil:
А действительно, почему?! Вопрос-то не праздный. :)

Фольклор, посвящённый перестановке значений двух переменных богат и многообразен. Одна из первых известных мне задач -- перестановка переменных в Алголе-60. (Знатоки истории программирования меня поймут, для остальных поясню: в Алголе-60 было два способа передачи параметров, по значению и по наименованию. По наименованию означала, что параметр как бы вписывается в место своего использования текстуально (при этом автоматически разрешается конфликт имен переменных). Например, если параметр -- a[j], и j поменялось, то поменялось и то, на какой элемент массива ссылается a[j].)

В те же благодатные времена люди экономили память. Её катастрофически не хватало -- адресное пространство БЭСМ-4 было 4096 слов. И всё.

Времена БЭСМ-4 прошли, а вместе с ними и эти моды. Попытаюсь ответить на вопрос: почему нет:

1) И самое главное: эту программу читать (человеку) ничуть не проще, чем предыдущую.

2) Далеко не очевидно, какая из программ будет быстрее. Это зависит от языка. Это зависит от процессора. В ещё большей степени это зависит от оптимизации компилятора. Причины: нормальный компилятор вообще оставит промежуточную переменную на регистре, не отводя под неё память. таким образом прямая перестановка сведётся к двум чтениям и двум записям. В тоже время, во всех этих "оптимизациях" присутствует арифметика, и даже если предположить, что компилятор сумеет не записывать в память промежуточные результаты, регистров понадобится куда больше. По опыту, компилятор вряд ли сообразит. А доступ к памяти ой как дорог.

3) Съэкономите ли Вы память -- не очевидно. С хорошим компилятором -- скорее всего нет. Правда, для этого лучше писать
Код:
{ int temp = a[z]; a[z] = a[x]; a[x] = temp; }
, подчёркивая временную сущность temp.

4) Этот трюк очень зависит от типа. Для вещественных, например, он уже не подходит. А применять нестандартные решения лучше только тогда, когда есть острая необходимость.

 
 
 
 
Сообщение10.01.2008, 00:35 
luitzen писал(а):
Код:
a[x]:=a[x]-a[z];
a[z]:=a[x]+a[z];
a[x]:=a[z]-a[x];

Почему бы не написать так? :-)


Потому что z может быть равным x. :D :D

 
 
 
 
Сообщение10.01.2008, 08:03 
luitzen писал(а):
Потому что z может быть равным x. :D :D

И так:
Код:
if x<>z then
begin
    a[x]:=a[x]-a[z];
    a[z]:=a[x]+a[z];
    a[x]:=a[z]-a[x];
end;
тоже лучше не делать :wink:

 
 
 [ Сообщений: 11 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group