Помощь - Поиск - Пользователи - Календарь
Полная версия: С++ нахождения площади и периметра треугольника по координатам > Информатика / Программирование
Образовательный студенческий форум > Другие дисциплины > Информатика / Программирование
Страницы: 1, 2
InFuz
В общем закончили 1 семестр и во втором начался C++ (был и остался Pascal)
Посоветуйте какую нибудь книжку или самоучитель по C++.
Пока читаю Г. Шилд "Самоучитель С++"

И помогите разобраться с 1 лабой. Мало того, что в С++ пока не рублю так еще и задача... я ее даже на листке не решу не то что уж прогу по ней писать.

Известны координаты вершин треугольника ABC: A(x1,y1), B(x2,y2) и C(x3,y3). Найти
его площадь и периметр.

Нашел в инете пару формул, хотя точно не уверен что те.
Вот, что пока смог накорябать.

# include <iostream.h>
# include <stdio.h>
# include <math.h>

int main()

{
int x1,x2,x3,y1,y2,y3;
double s,p,a,b,c;
cout<<"\n Лабораторная работа №1";
cout<<"\n x1="; cin>>x1;
cout<<"\n x2="; cin>>x2;
cout<<"\n x3="; cin>>x3;
cout<<"\n y1="; cin>>y1;
cout<<"\n y2="; cin>>y2;
cout<<"\n y3="; cin>>y3;
a = sqrt((x1-x2)^2+(y1-y2)^2);
b = sqrt((x1-x3)^2+(y1-y3)^2);
c = sqrt((x2-x3)^2+(y2-y3)^2);
p = a+b+c;
cout<<"\n p=" <<p;
/* cout<<"p="<<p;
s=(x1-x3)*(y2-y3)*(x2-x3)*(y1-y3)/2;
cout<<"s="<<s; */
}
Евгений М.
Формула Герона.

pp=p*0.5;
s=sqrt(pp*(pp-a)*(pp- b )*(pp-c));

Не забудьте объявить pp как double.
InFuz
Пару вопросов.
Что такое pp (p я так понимаю пириметр).
И как избавиться от ошибки когда вычисляется a, b, c и значение под корнем становиться отрицательным, например для треугольника а(1,1) b(-1,1) c(0,-1).
Pavlov Andrey
да pp - у него это периметр, а в Героне надо полу-периметр(p)
когда находишь длины сторон, поставь mod или abs (не помню, ну общем можно и самому написать функцию, возвращающую |x|(модуль) )))))
А хотя, я что то не понимаю, где там может быть отрицательное значение????
InFuz
да фиг его знает, когда вводишь а(1,1) b(-1,1) c(0,-1) выдает ошибку что значение под корнем отрицательное, хотя по формуле ничего подобного нет.

Сделал вот так вроде работает, только фиг его знает правильно считает или нет biggrin.gif
Попробую такую сдать.

# include <iostream.h>
# include <stdio.h>
# include <math.h>

int main()

{
int x1,x2,x3,y1,y2,y3;
double s,p,pp,a,b,c;
cout<<"\n Лабораторная работа №1";
cout<<"\n ";
cout<<"\n Введите x1="; cin>>x1;
cout<<" Ввидите y1="; cin>>y1;
cout<<" Введите x2="; cin>>x2;
cout<<" Ввидите y2="; cin>>y2;
cout<<" Ввидите x3="; cin>>x3;
cout<<" Ввидите y3="; cin>>y3;
a = sqrt (abs (((x1-x2)^2+(y1-y2)^2)));
b = sqrt (abs (((x1-x3)^2+(y1-y3)^2)));
c = sqrt (abs (((x2-x3)^2+(y2-y3)^2)));
p = a+b+c;
cout<<"\n p=" <<p;
pp=p/2;
//Формула Герона
s=sqrt(pp*(pp-a)*(pp- b )*(pp-c));
cout<<"\n s=" <<s;
}
Dimka
выведите на экран промежуточные значения a,b,c,p
abs- зачем используете?
InFuz
без abs выдает ошибку что значение под корнем отрицательное хотя это не так.
p и так выводит это по условию надо найти. вот с a b c еще

# include <iostream.h>
# include <stdio.h>
# include <math.h>

int main()

{
int x1,x2,x3,y1,y2,y3;
double s,p,pp,a,b,c;
cout<<"\n Лабораторная работа № 1";
cout<<"\n Вариант № 21";
cout<<"\n ";
cout<<"\n Введите x1="; cin>>x1;
cout<<" Ввидите y1="; cin>>y1;
cout<<" Введите x2="; cin>>x2;
cout<<" Ввидите y2="; cin>>y2;
cout<<" Ввидите x3="; cin>>x3;
cout<<" Ввидите y3="; cin>>y3;
a = sqrt (abs (((x1-x2)^2+(y1-y2)^2))); cout<<" a=" <<a ;
b = sqrt (abs (((x1-x3)^2+(y1-y3)^2))); cout<<"\n b=" <<b ;
c = sqrt (abs (((x2-x3)^2+(y2-y3)^2))); cout<<"\n c=" <<c ;
p = a+b+c;
cout<<"\n p=" <<p;
pp=p/2;
//Формула Герона
s=sqrt(pp*(pp-a)*(pp- b )*(pp-c));
cout<<"\n s=" <<s;
}
Dimka
да Вы не для меня выводите эти значения, а для себя.
Если без abs выдает "под корнем отрицательное значение",
sqrt ( (((x1-x2)^2+(y1-y2)^2)) )

то нужно вывести значение выражения, под корнем и проверить его на отрицательность. Если оно действительно отрицательно, значит или Вы что-то не то делаете или система считает неправильно
InFuz
Да я знаю что не для вас, не надо так сурово (:

как исправить ошибку function "sqr" should have a prototype;
здесь.
aa= sqr (x2-x3);
Dimka
sqr что ознгачает?
InFuz
возведение в квадрат.
граф Монте-Кристо
Видимо, в math.h нету такой функции. Можно написать её самому, либо вместо sqr(x) писать x*x. Можно ещё поюзать pow, но она работать будет дольше,чем x*x.
InFuz
я в принципе и хотел написать в виде х*х, просо с sqr (х) короче и аккуратнее бы получилось ну ладно напишу х*х
вот конечный вариант, щас все вроде правильно, ошибка была в том что она не понимала ^2 (и sqr) пришлось писать х*х

# include <iostream.h>
# include <stdio.h>
# include <math.h>

int main()

{
int x1,x2,x3,y1,y2,y3;
double s,p,pp,a,b,c,aa;
cout<<"\n Лабораторная работа № 1";
cout<<"\n ";
cout<<"\n Введите x1="; cin>>x1;
cout<<" Ввидите y1="; cin>>y1;
cout<<" Введите x2="; cin>>x2;
cout<<" Ввидите y2="; cin>>y2;
cout<<" Ввидите x3="; cin>>x3;
cout<<" Ввидите y3="; cin>>y3;
a = sqrt (((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))); cout<<" a=" <<a ;
b = sqrt (((x1-x3)*(x1-x3))+((y1-y3)*(y1-y3))); cout<<"\n b=" <<b ;
c = sqrt (((x2-x3)*(x2-x3))+((y2-y3)*(y2-y3))); cout<<"\n c=" <<c ;
p = a+b+c;
cout<<"\n p=" <<p;
pp=p/2;
//Формула Герона
s=sqrt(pp*(pp-a)*(pp- b )*(pp-c));
cout<<"\n s=" <<s;
}
Dimka
на счётах быстрее посчитаешь площадь. Уже 2 часа идет отладка программы
InFuz
biggrin.gif
если бы я лучше знал язык я бы может и после первой подсказки сделал все.
да и интернет форум куда медленнее для общения чем хотя бы icq
InFuz
Лаба №2

Определить, является ли последовательность из N произвольных чисел знакочереду-
ющейся.


Честно говоря, чот нет идей никаких. За окончание последовательности возьмем 0. А дальше чот даже не знаю с чего начать.

Шаблон:

# include <iostream.h>
# include <stdio.h>
# include <math.h>

int main()

{
int a;
cout<<"\n Лабораторная работа № 2";
cout<<"\n ";
cout<<"\n Введите элемент последовательности (конец последовательности - 0 -)";
cout<<"\n "; cin>>a;
cout<<"\n ";
while (a != 0);
{ ...
ыыы
...
cout <<"Последовательность знакочередующаяся";
cout <<"Последовательность не знакочередующаяся";
}
}
Vahappaday
Цитата(InFuz @ 12.3.2010, 17:36) *

Лаба №2

Определить, является ли последовательность из N произвольных чисел знакочередующейся.

Честно говоря, чот нет идей никаких. За окончание последовательности возьмем 0. А дальше чот даже не знаю с чего начать.


Код
# include <iostream>
# include <stdio.h>
# include <conio.h>

using namespace std;

int main()
{

    int a,b=0;
    bool alter=true;
    _wsetlocale(LC_ALL,L"Russian");
    cout<<"\n Лабораторная работа № 2";
    cout<<"\n ";
    cout<<"\n Введите элемент последовательности (конец последовательности - 0 -)";
    cout<<"\n "; cin>>a;
    while (a != 0)
    {
        if((a*b)>0)
        {
            alter=false;
        }
        b=a;
        cout<<"\n Введите элемент последовательности (конец последовательности - 0 -)";
        cout<<"\n "; cin>>a;
    }
    if(alter) cout <<"Последовательность знакочередующаяся";
    else cout <<"Последовательность не знакочередующаяся";
    getch();
    return 0;
}


Компилил в студии (Microsoft Visual Studio 2008), посему дам несколько комментариев:

1. # include <iostream> - <iostream.h> у меня студия просто не нашла, либо я что-то не так делаю, либо это и впрям устаревший заголовочный файл.

2. using namespace std; - обязательно, как без него работала прошлая лаба, удивляюсь.

3. _wsetlocale(LC_ALL,L"Russian"); - без этой строчки у меня, лично, бракозябри в консоли вместо русского языка.

4. getch() - ждёт ввода символа, добавил, чтобы можно было смотреть результат работы. Хотя, конечно, этого можно добиться и запуская по Ctrl+F5 в студии, наверное, и в вашей среде, если она отличается, есть что-то такое.

5. #include <conio.h> - нужно для работы getch();



Ещё какие-то комментарии нужны?
Кстати, на какой специальности учитесь? Что-то связанное с информатикой/программированием/ИТ или нет?
InFuz
я компилю в borland c++ 3.1 т.к. и сдавать лабы нужно в ней.
подредактировал под свой компилятор, вроде работает все норм, спасибо вам

# include <iostream.h>
# include <stdio.h>
# include <math.h>

int main()
{
int a,b=0,alter=1;
cout<<"\n Лабораторная работа № 2";
cout<<"\n ";
cout<<"\n Введите элемент последовательности (конец последовательности - 0 -)";
cout<<"\n"; cin>>a;
while (a != 0)
{
if((a*b )>0) //не понял как тут работает ведь b=0 и a*b всегда будет 0
{
alter=0;
}
b=a;
cin>>a;
}
if(alter) cout <<"Последовательность знакочередующаяся";
else cout <<"Последовательность не знакочередующаяся";
}

using namespace std; - обязательно, как без него работала прошлая лаба, удивляюсь.
это издержки моего компилятора.

Кстати, на какой специальности учитесь? Что-то связанное с информатикой/программированием/ИТ или нет?
да "Прикладная математика и информатика", в 1 семестре изучали Pascal (хотя и сейчас продолжаем), я его еще по школе более менее знал, так что с ним особых проблем небыло, а вот во 2 семестре еще C++ добавилось, вот учу потихоньку.
Vahappaday
Цитата(InFuz @ 12.3.2010, 21:06) *

да "Прикладная математика и информатика"

Тогда больше готового кода не будет, только подсказки))

Цитата(InFuz @ 12.3.2010, 21:06) *

if((a*b )>0) //не понял как тут работает ведь b=0 и a*b всегда будет 0


Чуть ниже есть строчка b=a;, она и меняет значение. Суть вот в чём. Мы каждую итерацию "запоминаем" значение предыдущего элемента в b.
В следующей итерации проверяем положительность произведения a*b - если произведение положительно, то предыдущий и текущий элемент одного знака - выставляем флаг и, фактически, дальше программу можно не выполнять.

Если же все произведения были неположительными (0 допустим для 1-й итерации, когда b=0), то флаг alter так и останется true, в конце выводится Последовательность знакочередующаяся. Если же хоть одно произведение было положительным, мы не можем считать такую последовательность положительной и выводим Последовательность не знакочередующаяся.

Кстати, зачем bool убрали? Судя по cin, cout используется STL. Раз используется STL - перед нами C++. Раз C++, то bool абсолютно корректен. Хотя... Вам виднее) Не видел я эту версию борланда и ничего утверждать не берусь)
InFuz
ясно, первая итерация как бы проходит в холостую (т.к. один элемент не является еще последовательностью).

да это С++, хотя # include <iostream.h> и отсутствие using namespace это как в С

в 3.1 нет типа bool как такового он появляется в версиях 5 и старше, так что приходится в место него использовать тип целых чисел где 0=false, а 1=true.
Vahappaday
Цитата(InFuz @ 13.3.2010, 9:56) *

ясно, первая итерация как бы проходит в холостую (т.к. один элемент не является еще последовательностью).

Именно так)
InFuz
Лаба №4

Дан массив целых простых чисел. Переписать все простые числа из заданного массива в другой массив. Первый массив упорядочить по возрастанию, второй по убыванию. Создать функции для для определения простого числа и для сортировки элементов массива.
P.S. "обязательное применение динамических массивов"


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

# include <iostream.h>
# include <stdio.h>
# include <math.h>
# include <conio.h>
# include <alloc.h>

int main()
{ clrscr();
int i,n;
float * a;
float s;
cout<<"n="; cin>>n;
a=(float *) malloe (n * sizeof(float)); //<==тута "function 'malloe' should have a prototype"
a=new float[n];
cout<<"El-ma \n";
for (i=0; i<n; i++) cin>>* (a+i);
s+=*(a+i);
cout<<"s=" <<s<<"\n";
return 0;
getch();
}


написал еще на pascale пока функцию для определения простое число или нет

Writeln('Vvedite 4islo');
Readln( R );
if (R = 1) or (R = 2) then Writeln('Prostoe 4islo')
else if (R mod 2 = 0) then Writeln('Sostavnoe 4islo')
else begin
I := 3;
while R mod I <> 0 do
I:= I + 2;
if R <= I then Write('Prostoe 4islo')
else Write('Sostavnoe 4islo');
end;


Vahappaday надеюсь на ваши подсказки ))
граф Монте-Кристо
Цитата(InFuz @ 30.3.2010, 16:28) *

a=(float *) malloe (n * sizeof(float)); //<==тута "function 'malloe' should have a prototype"

Не malloe, a malloc.
InFuz
biggrin.gif
Vahappaday
ой... а зачем и new и malloc? и ни разу не освобождена память))) ай-яй-яй))

Рекомендую почитать про выделение памяти в некоторых старых версиях Builder'a. Мне один опытный человек говорил, что у Borland был косяк либо с new/delete, либо с malloc/free, скорее с первым. Хотя я могу и ошибаться.

getch() после return 0; не имеет смысла.

Насчёт нового массива. Есть два варианта.
1. Функция сама изнутри сначала делает проход и считает.
2. Мы должны передавать функции указатель на уже выделенную область памяти.

Первый вариант.... понадёжней, что ли. Исключает ошибки при вызове.
Если будете делать по второму, то я бы сделал что-то типа

int CopySimples(float *src, float *dst);

И если передать dst=NULL, то ничего не копировать, а просто считать и возвращать количество элементов.
Затем выделять память под такое количество элементов и уже передавать нормальный указатель.

Я думаю в этом случае проще реализовать 1-й вариант.
Главное, не забывать освобождать память, а то привыкнете.

Ну, а насчёт определения простоты, это элементарно, тем более, что вариант уже есть, хотя на мой взгляд можно попроще структурно и ещё немножко оптимизировать.
Если уж совсем плохо будет, напишу, а так предлагаю потренироваться самостоятельно.

Насчёт сортировки: каким методом сортировать будем? Пузырьком? Чем-то посложнее? Можно вообще воспользоваться встроенным qsort'ом

Добавлено:
Пришла ещё мысль сделать функцию добавления массива к числу. То есть, мы должны выделить память на 1 больше имеющегося, скопировать старый в новый, дописать новое число, освободить память из под старого, вернуть указатель на новый.
Вариантов куча на самом деле))
Определяйтесь, и пробуйте писать. Где будет тяжело - подмогу.
InFuz
Пока делаю без функций т.к. с ними еще не разобрался.
Вот так пока получается, вроде переделал функцию из паскалевской без изменений, там работала, а тут чот ни фига

Код
# include <iostream.h>
# include <stdio.h>
# include <math.h>
# include <conio.h>
# include <alloc.h>

int main()
{//----------------------------------------------------------------
    clrscr();
    int w,i,j,n,s,g;
    int * yk;
    cout<<"n="; cin>>n;
    yk=new int[n];
    cout<<"El-ma \n";
    for (i=0; i<n; i++)
    { cin>>* (yk);
      s=*(yk);
      cout<<"\n s="<<s;
//----------------------------------------------------------------
      if (s==1 || s==2) { cout<<"\n s - Prostoe 4islo"; g=*(yk);
      cout<<"\n g="<<g;}
      if (s%2==0) cout<<"\n s - Sostavnoe 4islo";
      else
      {
    w=3;
    while (s&w!=0)
    { w=w+2;
      if (s<=w) { cout<<"\n s - Prostoe 4islo"; g=*(yk);
      cout<<"\n g="<<g; }
      else cout<<"\n s - Sostavnoe 4islo";
    }
      }
    }
//-----------------------------------------------------------------
    delete yk;
    getch();
}
Vahappaday
ой... не нравится мне этот код. Опишу в таком порядке, как бросилось в глаза.

1. Для освобождения памяти из под массива использовать надо
Код
delete []yk;

Вы же удаляете бедную память как объект.
2. Память под массив выделяете и так её и не используете.
Код
cin>>* (yk);

- это конечно здорово, что умеете пользоваться разыменовыванием, но тут всё делается проще.
Код
cin >> yk[i];

Так куда проще, а главное, так правильно)) Можно, конечно, инкрементировать указатель, но так он "испортится" - не будет уже указывать на начало массива.
3. Посмотрел, как определяется простота числа. Это плохо, так никто не пишет. 4 лаба, пора бы уже разобраться с функциями.
Вообще, суть функции понятен или нет? Функция обязана что-то возвращать. Пусть возвращает bool (ну, или int) - 0, если число составное, 1 - если простое.
4. Кстати о функциях: int main ничего не возвращает, это ошибка синтаксическая.

Это всё "стопроцентные" ошибки, я уже молчу про то, что код трудночитаем, плохо структурирован. К хорошему стилю лучше привыкать сразу.

Советую написать-таки функцию типа bool, ну или в вашем случае int...
int IsSimple(int x), которая отвечала бы за определение простоты числа. Сложное - возвращаем 0. Дошла до конца проверки - значит, число простое, возвращаем 1. Это обязательно хотя бы потому, что определение простоты здесь не самоцель а лишь служебная функция, которая используется как один из кусочков выполнения итоговой задачи.

Когда напишете, будем разбираться с сортировкой и копированием.

Массив нужно не просто завести, но и скопировать в него все входные числа. Как это сделать, я описал чуть выше.
InFuz
Гляньте функцию, еще хотел спросить как х присвоить yk[i]? Короче давайте еще подсказок, суть то функций понятен я имел в виду еще не совсем разобрался/"набил руку" как это все оформляется/выгядит конкретно в программе. Последовательность расположения функций в программе их взаимодействие другу с другом. От паскаля еще отвыкнуть не могу ))

Код
# include <iostream.h>
# include <stdio.h>
# include <math.h>
# include <conio.h>
# include <alloc.h>

int main()
{
      clrscr();
//----------------------------------------------------------------
      int Chislo(int x);
      int i,n,j;
      {
    Chislo=0;
    for (i=0; i<n; i++)
    {
      if (x[i]%2==0) Chislo=0;
      else for (j=1; j>sqrt(x[i]); j+2)
        {
          if (x[i]%j!=0) Chislo=1;
          else
          {
        Chislo=0;
        break;
          }
        }
    }
      }
//-----------------------------------------------------------------
    int w,i,j,n,s,g;
    int yk[99];
    cout<<"n="; cin>>n;
    yk=new int[n];
    cout<<"El-ma \n";
    for (i=0; i<n; i++)
    {
      cin>>yk[i];
      s=yk[i];
      cout<<"\n s="<<s;
    }
//-----------------------------------------------------------------
    delete []yk;
    getch();
}
Vahappaday
На мой взгляд, вновь неверно... Теоретически функцию можно описывать внутри другой функции, но я не видел, чтоб к этому прибегали.

У Вас же Chislo описана внутри main.

Также советую разобраться в синтаксисе определения функции.

Код
[тип возвращаемого значения] [имя функции]([список параметров])
{
[код]
}


Никакой переменной с именем функции по умолчанию не создаётся. Все возвраты осуществляются оператором return.

Захотели вернуть 0, пишем return 0;
Захотели вернуть 1, пишем return 1;
Захотели вернуть x, пишем return x;

После выполнения оператора return выполнение функции прекращается и управление передаётся вызывающей функции.

Объявлять все локальные переменные нужно уже в теле функции, там, где у меня написано [код].

То есть, если вы всё вот этот осознаете, то поймёте, что функция описана неверно.

Остальные комментарии:
1. опять main ничего не возвращает - чего вы её так обижаете, такая же функция) Обещает отдавать int, значит, должна отдавать int))
2. Зачем int yk[99]? Зачем Вы выделили память в стеке? Вы же её не используете...
3.
Цитата
как х присвоить yk[i]?

А никак) Просто пишете
Код
Chislo(yk[i]);
и всё


Вот небольшой примерчик с оформлением функций. У меня массив статический, но Вам так нельзя, не подходит по условию статический.

Код

int IsSimple(int x)
{
    int i;
    if (x<2) return 0; //если меньше двух, дальше функция не будет выполняться
    for(i=2;i<x;i++)
    {
        if(!(x%i))
        {
            return 0; //есть делитель больший или равный двойке, но меньше числа, опять же прекращаем
        }
    }
    return 1; //делителей не нашлось, число простое
}

int main()
{
    int i;
    int x[50];
    for(i=0;i<50;i++)
    {
        cin >> x[i];
        if(IsSimple(x[i])) cout << "Prostoe\n";
        else cout << "Sostavnoe\n";
    }
    return 0; //заметьте, обещал вернуть int и вернул int
}

InFuz
(i=2;i<x;i++)?
Разве может быть делителем x число которое >1/2x (например числа >5 не могут быть делителями 10)
можно сократитть количество проверок в цикле почти в 2 раза.

С функциями вроде разобрались, терь надо с дин. массивом разобраться.

yk[99] - получается статический
*(yk) - тоже не верно а как тогда?

Код
# include <iostream.h>
# include <stdio.h>
# include <math.h>
# include <conio.h>
# include <alloc.h>

//----------------------------------------------------------------
    int Chislo(int x)
    {
      int j;
      if (x<4) return 1;
      else
       {
         for (j=2; j<floor(x/2)+1; j++)
         if (x%j==0) return 0;
       }
       return 1;
    }
//-----------------------------------------------------------------
    int mani()
    {
      clrscr();
      int w,i,j,n,s,g,yk;
      cout<<"n="; cin>>n;
      yk=new int[n];
      cout<<"El-ma \n";
      for (i=0; i<n; i++)
      {
         cin>>yk[i];
         s=yk[i];
         cout<<"\n s="<<s;
         if (Chislo(yk[i])) cout<<"Prostoe\n";
         else cout<<"Sostavnoe\n";
      }
      delete []yk;
      getch();
      return 0;
    }
Vahappaday
Цитата(InFuz @ 1.4.2010, 10:33) *

(i=2;i<x;i++)?
Разве может быть делителем x число которое >1/2x (например числа >5 не могут быть делителями 10)
можно сократитть количество проверок в цикле почти в 2 раза.


Тогда уж не до x/2 а до sqrt(x), обычно делается так, не стал писать, чтоб не усложнять.

Цитата(InFuz @ 1.4.2010, 10:33) *

yk[99] - получается статический
*(yk) - тоже не верно а как тогда?


Объявлять и выделять память так:

Код
int* yk = new int[n]


Обращаться же по индексу

Код
cin>>yk[i];
s=yk[i];


Пробуйте сортировать. Для сортировки сделайте функцию, которая в качестве параметра принимает указатель на начало массива. Можно конечно qsort, но так неинтересно.
InFuz
Вот отлаженный вариант

Код
# include <iostream.h>
# include <stdio.h>
# include <math.h>
# include <conio.h>
# include <alloc.h>

//----------------------------------------------------------------
    int Chislo(int x)
    {
      int j;
      if (x<4) return 1;
      else
       {
         for (j=2; j<ceil(sqrt(x))+1; j++)
         if (x%j==0) return 0;
       }
       return 1;
    }
//-----------------------------------------------------------------
    int main()
    {
      clrscr();
      int w,i,j,n,s,g;
      cout<<"n="; cin>>n;
      int* yk = new int[n];
      cout<<"El-ma \n"<<"\n";
      for (i=0; i<n; i++)
      {
    cin>>yk[i];
    s=yk[i];
    cout<<"s["<<i<<"]="<<s;
    if (Chislo(yk[i])) cout<<" - Prostoe\n"<<"\n";
    else cout<<" - Sostavnoe\n"<<"\n";
      }
      delete []yk;
      getch();
      return 0;
    }


прежде чем сорировать надо еще переписать в другой массив, а qsort что конкретно делает?
надо сегодня доделать, а то завтро уже здавать.
InFuz
Код
# include <iostream.h>
# include <stdio.h>
# include <math.h>
# include <conio.h>
# include <alloc.h>

//----------------------------------------------------------------
    int Chislo(int x)
    {
      int j;
      if (x<4) return 1;
      else
       {
         for (j=2; j<ceil(sqrt(x))+1; j++)
         if (x%j==0) return 0;
       }
       return 1;
    }
//-----------------------------------------------------------------
    int main()
    {
      clrscr();
      int k,j,i,n; j=0; k=0;
      cout<<"n="; cin>>n;
      int* mas1 = new int[n];
      int* mas2 = new int[n];
      cout<<"El-ma \n"<<"\n";
      for (i=0; i<n; i++)
      {
         cin>>mas1[i];
         if (Chislo(mas1[i])) {mas2[j]=mas1[i]; j=j+1; k=k+1;}
                }
      for (i=0; i<n; i++)
      {
    cout<<"\nmas1["<<i<<"]="<<mas1[i];
      }
      cout<<"\n";
      for (j=0; j<k; j++)
      {
        cout<<"\nmas2["<<j<<"]="<<mas2[j];
      }
      delete []mas1;
      delete []mas2;
      getch();
      return 0;
    }


вся щас буду сортировку пробовать делать.
сортироваку тоже надо в виде функции делать.

P.S. тут вопрос один. я под 2 массив виделяю памяти тоже n хотя там может столько и не потребоваться, как заранее просчитать сколько под него памяти веделять? или это не принципиально?
Vahappaday
qsort - быстрая сортировка, хороший алгоритм, вопрос, зачтут ли его Вам.
Что делает? Сортирует массив. Требует указатель на массив, количество элементов, размер одного элемента и функцию сравнения.
Вот тут хорошо описано, как раз для Вашего случая простых чисел.

http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/

Под второй массив можно выделять и меньше. Для этого достаточно посчитать, сколько простых чисел, а потом ещё раз прогнать и скопировать. А можно выделить и столько же... Смотреть надо на объёмы данных и учитывать, что важнее - скорость обработки или экономичность по памяти.

Сортировку, наверное, лучше написать свою. Пусть медленную, хоть пузырьком, но свою. Полезно))
InFuz
Чот не знаю как пузырек оформить в виде функции, если просто в main дописать понятно, а как в функцию сортировки передать все значения что бы он с ними работала?

Хочу в функции сортировки сделать копию массива с которым надо рабоать, потом там его отсортировать и печатать то что получилось.
Vahappaday
Цитата(InFuz @ 2.4.2010, 17:09) *

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


Плохое решение. Если Вы передаёте указатель на начало массива и количество элементов в нём, то изменяя элементы массива по указателю, Вы изменяете исходный массив. То есть, изменения будут "видны" и в вызывающей функции.

Вы понимаете, чем отличаются локальные данные и глобальные, данные кучи и данные стека?
Это то, с чего нам начали объяснять С на 1 курсе. И это правильно!
Это надо понимать. В С/С++ надо уметь работать с указателями, вот мне и интересно, у Вас с этим всё ок?

Поскольку сдавать завтра, скажу так: достаточно отсортировать массив по указателю, никуда его не копируя. А уже в main выводить его и всё прочее.

Но вообще рекомендую с указателями разобраться.
В качестве упражнения: выделите корректно память под трёхмерный массив, передайте его в функцию, отсортируйте как-нибудь, например, сначала по x, потом по y, потом по z (порядок сортировки сами выберите). А потом напечатайте и освободите корректно память - крайне полезное упражнения для начала.

PS. Если такие уж сильные проблемы с сортировкой, пузырёк могу по-быстрому написать))
InFuz
Вот пузырек реалезованый не как функция.

Код
# include <iostream.h>
# include <stdio.h>
# include <math.h>
# include <conio.h>
# include <alloc.h>

//-----------------------------------------------------------------
    int Chislo(int x)
    {
      int j;
      if (x<4) return 1;
      else
       {
         for (j=2; j<ceil(sqrt(x))+1; j++)
         if (x%j==0) return 0;
       }
       return 1;
    }
//-----------------------------------------------------------------
   /* int Sort()
    {
      return 0;
    } */
//-----------------------------------------------------------------
    int main()
    {
      clrscr();
      int t,k,i2,j,j2,i,n; j=0; k=0;
      cout<<"n="; cin>>n;
      int* mas1 = new int[n];
      int* mas2 = new int[n];
      cout<<"El-ma \n"<<"\n";
      for (i=0; i<n; i++)
      {
    cin>>mas1[i];
      }
      for (i=0; i<n; i++)
      {
    cout<<"\nmas1["<<i<<"]="<<mas1[i];
      }
      cout<<"\n";
//-----------------------------------------------------------------
      for (i2=1; i2<n; i2++)
   {
      for (i=0; i<n-1; i++)
      {
    if (mas1[i]>mas1[i+1])
    {
      t=mas1[i];
      mas1[i]=mas1[i+1];
      mas1[i+1]=t;
    }
      }
   }
//-----------------------------------------------------------------
      for (i=0; i<n; i++)
      {
    cout<<"\nmas1["<<i<<"]="<<mas1[i];
      }
      cout<<"\n";
      for (i=0; i<n; i++)
      {
    if (Chislo(mas1[i])==1) {mas2[j]=mas1[i]; j=j+1; k=k+1;}
      }
      for (j=0; j<k; j++)
      {
    cout<<"\nmas2["<<j<<"]="<<mas2[j];
      }
      cout<<"\n";
//-----------------------------------------------------------------
      for (j2=1; j2<k; j2++)
   {
      for (j=0; j<k-1; j++)
      {
    if (mas2[j]<mas2[j+1])
    {
      t=mas2[j];
      mas2[j]=mas2[j+1];
      mas2[j+1]=t;
    }
      }
   }
//-----------------------------------------------------------------
      for (j=0; j<k; j++)
      {
    cout<<"\nmas2["<<j<<"]="<<mas2[j];
      }
      delete []mas1;
      delete []mas2;
      getch();
      return 0;
    }
Vahappaday
а в чём проблема реализации как функции? Ведь то же самое!

Кстати, это нельзя считать ошибкой, но зачем Вы пишете, скажем,
j=j+1;

Ведь есть такой классный оператор инкремента)
j++;
Наверное, он даже где-то чуть-чуть оптимальнее. Рекомендую))
InFuz
j=j+1;
не знаю наверно привычка с паскаля еще так нагляднее, в паскалее вообщето то же есть альтернатива j:=j+1 или inc(j) ))

а че тоже самое то? )) функция она,... допустим считывает 1 элемент но там нельзя в самой функции написать mas1[i+1] т.к. у нее нет самоого массива и несчем сравнить, а на следующей итерации уже нет предыдущего [i-1].

P.S. приняли в таком виде, там было не принцепиально, главное чтобы функции вообще были ну у меня и была одна Chislo.
Vahappaday
В функцию нужно передавать весь массив, а не один элемент. Тогда после возврата из функции у вас на месте старого будет отсортированный массив.

например так

Код

void swap(int *p)
{
    int t=p[0];
    p[0]=p[1];
    p[1]=t;
}

void sort(int *arr, int n)
{
    int once_again, i;
    do
    {
        once_again=0;
        for(i=0;i<n-1;i++)
        {
            if(arr[i]<arr[i+1])
            {
                swap(arr+i);
                once_again=1;
            }
        }
    }while(once_again);
}


Это простейший пузырёк, реализованный в виде функции. Сортирует по возрастанию. Принимает указатель на начало и количество элементов.
InFuz
Final

Код
# include <iostream.h>
# include <stdio.h>
# include <math.h>
# include <conio.h>
# include <alloc.h>

//-----------------------------------------------------------------
    int Chislo(int x)
    {
      int j;
      if (x<4) return 1;
      else
       {
         for (j=2; j<ceil(sqrt(x))+1; j++)
         if (x%j==0) return 0;
       }
       return 1;
    }
//-----------------------------------------------------------------
    void swap(int *p)
    {
      int t=p[0];
      p[0]=p[1];
      p[1]=t;
    }
//-----------------------------------------------------------------
    void sort1(int *mas1, int n)
    {
      int again,i;
      do
      {
    again=0;
    for(i=0;i<n-1;i++)
    {
      if(mas1[i]>mas1[i+1])
      {
        swap(mas1+i);
        again=1;
      }
    }
      }
      while(again);
    }
//-----------------------------------------------------------------
    void sort2(int *mas2, int k)
    {
      int again,i;
      do
      {
    again=0;
    for(i=0;i<k-1;i++)
    {
      if(mas2[i]<mas2[i+1])
      {
        swap(mas2+i);
        again=1;
      }
    }
      }
      while(again);
    }
//-----------------------------------------------------------------
    void main()
    {
      clrscr();
      int t,k,i2,j,j2,i,n; j=0; k=0;
      cout<<"n="; cin>>n;
      int* mas1 = new int[n];
      int* mas2 = new int[n];
      cout<<"El-ma \n"<<"\n";
      for (i=0; i<n; i++)
      {
    cin>>mas1[i];
      }
      for (i=0; i<n; i++)
      {
    cout<<"\nmas1["<<i<<"]="<<mas1[i];
      }
      cout<<"\n";
      sort1(mas1,n);
      for (i=0; i<n; i++)
      {
    cout<<"\nmas1["<<i<<"]="<<mas1[i];
      }
      cout<<"\n";
      for (i=0; i<n; i++)
      {
    if (Chislo(mas1[i])==1) {mas2[j]=mas1[i]; j=j+1; k=k+1;}
      }
      for (j=0; j<k; j++)
      {
    cout<<"\nmas2["<<j<<"]="<<mas2[j];
      }
      cout<<"\n";
      sort2(mas2,k);
      for (j=0; j<k; j++)
      {
    cout<<"\nmas2["<<j<<"]="<<mas2[j];
      }
      delete []mas1;
      delete []mas2;
      getch();
    }


Один вопрос
swap пишиться для экономии места и времени или нет?
что измениться если написать

Код
void sort1(int *mas1, int n)
    {
      int again,i,t;
      do
      {
    again=0;
    for(i=0;i<n-1;i++)
    {
      if(mas1[i]>mas1[i+1])
      {
        t=p[i];
        p[i]=p[i+1];
        p[i+1]=t;
        again=1;
      }
    }
      }
      while(again);
    }
Vahappaday
Ответ: конкретно так работать не будет, потому что переменная p в функции sort не объявлена.
А вообще, swap я написал для наглядности кода, он так понятнее.
Естественно, можно и в теле sort1/sort2 менять местами элементы массива - не возбраняется.

Остальное не глядел, работает, в принципе?
InFuz
Ну вот тот что сверху полностью рабочий вариант, в точности совпадающий с тем что требовалось в задании.
InFuz
Лаба №6

Создать двоичный файл и записать в него n вещественных чисел. Сформировать массив из элементов исходного файла, внеся в него числа, превосходящие среднее значение положительных элементов файла. Задание должно быть выполнено в виде 2 программ. Первая должна сформировать бинарный файл. Вторая должна выполнить задание в соответствии с вариантом (см. выше).

Сделал 1 часть.
Во второй части сделал пока чтобы читала файл и записывала это все дело в массив, не понял что значит "внеся в него числа, превосходящие среднее значение положительных элементов файла", это просто что ли любых чисел которые соответствуют условию натыкать?
Vahappaday
Нет, все числа из файла, удовлетворяющие условию, я так понял задание.
InFuz
А я понял, вроде. Надо из файла брать (и добавлять в массив) только те числа которые соответствуют условию.
Vahappaday
да, только сначала для расчёта условий надо сначала все их прочитать
InFuz
Гляньте пожалуйста вроде должна работать, но чот ни фига не хочет blush.gif

1 часть

Код
# include <iostream.h>
# include <stdio.h>
# include <conio.h>

//-----------------------------------------------------------------
    void main()
    {
      clrscr();
      FILE *f;
      int i,n;
      double a;
      f=fopen("binfile.dat","wb");
      cout<<"n="; cin>>n;
      fwrite(&n, sizeof(int),1,f);
      for(i=0; i<n; i++)
      {
    cout<<"a["<<i<<"]="; cin>>a;
    fwrite(&a, sizeof(double),1,f);
      }
      fclose(f);
    }


2 часть

Код
# include <iostream.h>
# include <stdio.h>
# include <conio.h>

//-----------------------------------------------------------------
    void main()
    {
      clrscr();
      FILE *f;
      int i,n,t=-1,s=0,sym=0;
      double *a,*b;
      cout<<"n="; cin>>n;
      f=fopen("binfile.dat","rb");
      fread(a,sizeof(int),1,f);
      a-new double[n];
      fread(a,sizeof(double),n,f);
      for(i=0; i<n; i++)
      {
    if(a[i]>0)
    {
          sym=sym+a[i];
          s++;
    }
      }
      b-new double[s];
      for(i=0; i<s; i++)
      {
    if(a[i]>(sym/s))
    {
          t++;
      b[t]=a[i];
        }
      }
      for(i=0; i<t+1; i++)
      if (t=-1) cout<<"Net takix 4isel!";
      else
      {
        cout<<"\n"<<b[i]<<"\t";
    cout<<endl;
      }
      fclose(f);
      delete[]a;
      delete[]b;
      getch();
    }
Vahappaday
Есть много комментариев по 2 части.

Зачем записывать в файл n, а потом вводить его с клавы? Что-то уж одно)

fread(a,sizeof(int),1,f); - во-первых, надо сначала выделить память под указатель, а потом уж читать в него.
во-вторых, зачем читать в массив double? Формально ничего криминального, там тип входного параметра void*, но логики не вижу.
Тут уж Вы должны n прочитать.

a-new double[n]; - очепяточка?

sym=sym+a[i]; - вообще ужас))) Куда дробные части денутся?) К целому прибавлять double'ы, это надо же.

if(a[i]>(sym/s)) - а Вы в курсе, что sym / s -это целочисленное деление? Если делить одно целое на другое, то получится опять же целое. Например 10/3 = 3
А сравниваете Вы с double, так что ошибки вполне могут иметь место)

Последние две ошибки убиваются одним выстрелом: объявлением sym как double.

b-new double[s]; - и вновь очепяточка. Да, кстати, и почему именно s? Их там всегда будет меньше.

if (t=-1) cout<<"Net takix 4isel!"; - целых два косяка. Во-первых, (t==-1), во-вторых, если уж t и принимает такое значение, то цикл не прогонится не разу. Так что следует сделать if, а уж внутри if цикл.

Остальное дело вкуса. Хотя мне лично непонятно, почему в одном случае потоки cin и cout, а в другом fopen, fread, fwrite - либо STL, либо C Library)
InFuz
Все исправил, заработала.

Гляньте еще одну прогу.

Задание. Вычислить среднее значение элементов, расположенных в массиве между первым и последним нулевым значением. Поменять местами минимальный и максимальный элементы. Создать функции для определения среднего значения, макс. и мин.

Код
# include <iostream.h>
# include <stdio.h>
# include <math.h>
# include <conio.h>
# include <alloc.h>

//-----------------------------------------------------------------
    double Sred(int *a, int I, int I2)
    {
      int i,s=0,sym=0;
      for(i=I+1; i<I2-1; i++)
      {
    sym=sym+a[i];
        s++;
      }
      return (sym/s);
    }
//-----------------------------------------------------------------
    void MaxMin(int *a, int n)
    {
      int b,i,max=0,imax;
      for(i=0; i<n; i++)
      {
    if(a[i]>max)
        {
      imax=i;
      max=a[i];
        }
      }
      int min=0,imin;
      for(i=0; i<n; i++)
      {
    if(a[i]<min)
        {
      imin=i;
      min=a[i];
        }
      }
      b=max;
      a[imax]=a[imin];
      a[imin]=max;
    }
//-----------------------------------------------------------------
    int main()
    {
      clrscr();
      int b,i,I,n,I2,s=0;
      cout<<"n="; cin>>n;
      int* a = new int[n];
      cout<<"El-ma";
      for (i=0; i<n; i++)
      {
    cout<<"\na["<<i<<"]=";
    cin>>a[i];
        if(a[i]==0) s++;
      }
      if(s<2)
      {
    cout<<"Malo nylei!\n";
        return 0;
      }
      else
      {
    for (i=0; i<n; i++)
    if(a[i]==0)
        {
      I=i;
      break;
    }
    for (i=n; i>I; i--)
    {
      if(a[i]==0)
      {
        I2=i;
            break;
          }
        }
      }
      Sred(a,I,I2);
      MaxMin(a,n);
      for (i=0; i<n; i++)
    cout<<"\na["<<i<<"]="<<a[i];
      cout<<"Srednee zna4enie="<<Sred;
      delete []a;
      getch();
      return 1;
    }
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.
Русская версия Invision Power Board © 2001-2024 Invision Power Services, Inc.