InFuz
Сообщение
#53889 11.3.2010, 14:16
В общем закончили 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; */
}
Евгений М.
Сообщение
#53894 11.3.2010, 15:09
Формула Герона.
pp=p*0.5;
s=sqrt(pp*(pp-a)*(pp- b )*(pp-c));
Не забудьте объявить pp как double.
InFuz
Сообщение
#53905 11.3.2010, 16:15
Пару вопросов.
Что такое pp (p я так понимаю пириметр).
И как избавиться от ошибки когда вычисляется a, b, c и значение под корнем становиться отрицательным, например для треугольника а(1,1) b(-1,1) c(0,-1).
Pavlov Andrey
Сообщение
#53906 11.3.2010, 16:25
да pp - у него это периметр, а в Героне надо полу-периметр(p)
когда находишь длины сторон, поставь mod или abs (не помню, ну общем можно и самому написать функцию, возвращающую |x|(модуль) )))))
А хотя, я что то не понимаю, где там может быть отрицательное значение????
InFuz
Сообщение
#53911 11.3.2010, 18:01
да фиг его знает, когда вводишь а(1,1) b(-1,1) c(0,-1) выдает ошибку что значение под корнем отрицательное, хотя по формуле ничего подобного нет.
Сделал вот так вроде работает, только фиг его знает правильно считает или нет

Попробую такую сдать.
# 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
Сообщение
#53912 11.3.2010, 18:20
выведите на экран промежуточные значения a,b,c,p
abs- зачем используете?
InFuz
Сообщение
#53914 11.3.2010, 18:37
без 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
Сообщение
#53915 11.3.2010, 18:46
да Вы не для меня выводите эти значения, а для себя.
Если без abs выдает "под корнем отрицательное значение",
sqrt ( (((x1-x2)^2+(y1-y2)^2)) )
то нужно вывести значение выражения, под корнем и проверить его на отрицательность. Если оно действительно отрицательно, значит или Вы что-то не то делаете или система считает неправильно
InFuz
Сообщение
#53916 11.3.2010, 19:09
Да я знаю что не для вас, не надо так сурово (:
как исправить ошибку function "sqr" should have a prototype;
здесь.
aa= sqr (x2-x3);
Dimka
Сообщение
#53917 11.3.2010, 19:34
sqr что ознгачает?
InFuz
Сообщение
#53918 11.3.2010, 19:35
возведение в квадрат.
граф Монте-Кристо
Сообщение
#53919 11.3.2010, 19:42
Видимо, в math.h нету такой функции. Можно написать её самому, либо вместо sqr(x) писать x*x. Можно ещё поюзать pow, но она работать будет дольше,чем x*x.
InFuz
Сообщение
#53923 11.3.2010, 19:51
я в принципе и хотел написать в виде х*х, просо с 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
Сообщение
#53924 11.3.2010, 19:54
на счётах быстрее посчитаешь площадь. Уже 2 часа идет отладка программы
InFuz
Сообщение
#53925 11.3.2010, 19:59

если бы я лучше знал язык я бы может и после первой подсказки сделал все.
да и интернет форум куда медленнее для общения чем хотя бы icq
InFuz
Сообщение
#53946 12.3.2010, 17:36
Лаба №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
Сообщение
#53955 12.3.2010, 19:54
Цитата(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
Сообщение
#53956 12.3.2010, 21:06
я компилю в 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
Сообщение
#53957 12.3.2010, 21:32
Цитата(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
Сообщение
#53959 13.3.2010, 9:56
ясно, первая итерация как бы проходит в холостую (т.к. один элемент не является еще последовательностью).
да это С++, хотя # include <iostream.h> и отсутствие using namespace это как в С
в 3.1 нет типа bool как такового он появляется в версиях 5 и старше, так что приходится в место него использовать тип целых чисел где 0=false, а 1=true.
Vahappaday
Сообщение
#53962 13.3.2010, 11:00
Цитата(InFuz @ 13.3.2010, 9:56)

ясно, первая итерация как бы проходит в холостую (т.к. один элемент не является еще последовательностью).
Именно так)
InFuz
Сообщение
#54888 30.3.2010, 12:28
Лаба №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 надеюсь на ваши подсказки ))
граф Монте-Кристо
Сообщение
#54891 30.3.2010, 13:05
Цитата(InFuz @ 30.3.2010, 16:28)

a=(float *) malloe (n * sizeof(float)); //<==тута "function 'malloe' should have a prototype"
Не malloe, a malloc.
InFuz
Сообщение
#54901 30.3.2010, 15:00
Vahappaday
Сообщение
#54926 31.3.2010, 4:07
ой... а зачем и 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
Сообщение
#54950 31.3.2010, 10:54
Пока делаю без функций т.к. с ними еще не разобрался.
Вот так пока получается, вроде переделал функцию из паскалевской без изменений, там работала, а тут чот ни фига
Код
# 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
Сообщение
#54958 31.3.2010, 14:52
ой... не нравится мне этот код. Опишу в таком порядке, как бросилось в глаза.
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
Сообщение
#54972 31.3.2010, 16:18
Гляньте функцию, еще хотел спросить как
х присвоить
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
Сообщение
#54974 31.3.2010, 16:43
На мой взгляд, вновь неверно... Теоретически функцию можно описывать внутри другой функции, но я не видел, чтоб к этому прибегали.
У Вас же 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
Сообщение
#55017 1.4.2010, 10:33
(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
Сообщение
#55047 1.4.2010, 18:39
Цитата(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
Сообщение
#55154 2.4.2010, 14:38
Вот отлаженный вариант
Код
# 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
Сообщение
#55155 2.4.2010, 14:52
Код
# 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
Сообщение
#55158 2.4.2010, 16:26
qsort - быстрая сортировка, хороший алгоритм, вопрос, зачтут ли его Вам.
Что делает? Сортирует массив. Требует указатель на массив, количество элементов, размер одного элемента и функцию сравнения.
Вот тут хорошо описано, как раз для Вашего случая простых чисел.
http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/Под второй массив можно выделять и меньше. Для этого достаточно посчитать, сколько простых чисел, а потом ещё раз прогнать и скопировать. А можно выделить и столько же... Смотреть надо на объёмы данных и учитывать, что важнее - скорость обработки или экономичность по памяти.
Сортировку, наверное, лучше написать свою. Пусть медленную, хоть пузырьком, но свою. Полезно))
InFuz
Сообщение
#55160 2.4.2010, 17:09
Чот не знаю как пузырек оформить в виде функции, если просто в main дописать понятно, а как в функцию сортировки передать все значения что бы он с ними работала?
Хочу в функции сортировки сделать копию массива с которым надо рабоать, потом там его отсортировать и печатать то что получилось.
Vahappaday
Сообщение
#55201 2.4.2010, 19:30
Цитата(InFuz @ 2.4.2010, 17:09)

Хочу в функции сортировки сделать копию массива с которым надо рабоать, потом там его отсортировать и печатать то что получилось.
Плохое решение. Если Вы передаёте указатель на начало массива и количество элементов в нём, то изменяя элементы массива по указателю, Вы изменяете исходный массив. То есть, изменения будут "видны" и в вызывающей функции.
Вы понимаете, чем отличаются локальные данные и глобальные, данные кучи и данные стека?
Это то, с чего нам начали объяснять С на 1 курсе. И это правильно!
Это надо понимать. В С/С++ надо уметь работать с указателями, вот мне и интересно, у Вас с этим всё ок?
Поскольку сдавать завтра, скажу так: достаточно отсортировать массив по указателю, никуда его не копируя. А уже в main выводить его и всё прочее.
Но вообще рекомендую с указателями разобраться.
В качестве упражнения: выделите корректно память под трёхмерный массив, передайте его в функцию, отсортируйте как-нибудь, например, сначала по x, потом по y, потом по z (порядок сортировки сами выберите). А потом напечатайте и освободите корректно память - крайне полезное упражнения для начала.
PS. Если такие уж сильные проблемы с сортировкой, пузырёк могу по-быстрому написать))
InFuz
Сообщение
#55221 2.4.2010, 21:45
Вот пузырек реалезованый
не как функция.
Код
# 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
Сообщение
#55227 3.4.2010, 5:13
а в чём проблема реализации как функции? Ведь то же самое!
Кстати, это нельзя считать ошибкой, но зачем Вы пишете, скажем,
j=j+1;
Ведь есть такой классный оператор инкремента)
j++;
Наверное, он даже где-то чуть-чуть оптимальнее. Рекомендую))
InFuz
Сообщение
#55240 3.4.2010, 9:21
j=j+1;
не знаю наверно привычка с паскаля еще так нагляднее, в паскалее вообщето то же есть альтернатива j:=j+1 или inc(j) ))
а че тоже самое то? )) функция она,... допустим считывает 1 элемент но там нельзя в самой функции написать mas1[i+1] т.к. у нее нет самоого массива и несчем сравнить, а на следующей итерации уже нет предыдущего [i-1].
P.S. приняли в таком виде, там было не принцепиально, главное чтобы функции вообще были ну у меня и была одна Chislo.
Vahappaday
Сообщение
#55256 3.4.2010, 13:34
В функцию нужно передавать весь массив, а не один элемент. Тогда после возврата из функции у вас на месте старого будет отсортированный массив.
например так
Код
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
Сообщение
#55418 6.4.2010, 9:08
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
Сообщение
#55433 6.4.2010, 13:32
Ответ: конкретно так работать не будет, потому что переменная p в функции sort не объявлена.
А вообще, swap я написал для наглядности кода, он так понятнее.
Естественно, можно и в теле sort1/sort2 менять местами элементы массива - не возбраняется.
Остальное не глядел, работает, в принципе?
InFuz
Сообщение
#55473 6.4.2010, 19:13
Ну вот тот что сверху полностью рабочий вариант, в точности совпадающий с тем что требовалось в задании.
InFuz
Сообщение
#56613 20.4.2010, 14:38
Лаба №6
Создать двоичный файл и записать в него n вещественных чисел. Сформировать массив из элементов исходного файла, внеся в него числа, превосходящие среднее значение положительных элементов файла. Задание должно быть выполнено в виде 2 программ. Первая должна сформировать бинарный файл. Вторая должна выполнить задание в соответствии с вариантом (см. выше).
Сделал 1 часть.
Во второй части сделал пока чтобы читала файл и записывала это все дело в массив, не понял что значит "внеся в него числа, превосходящие среднее значение положительных элементов файла", это просто что ли любых чисел которые соответствуют условию натыкать?
Vahappaday
Сообщение
#56618 20.4.2010, 15:36
Нет, все числа из файла, удовлетворяющие условию, я так понял задание.
InFuz
Сообщение
#56622 20.4.2010, 16:33
А я понял, вроде. Надо из файла брать (и добавлять в массив) только те числа которые соответствуют условию.
Vahappaday
Сообщение
#56636 20.4.2010, 18:27
да, только сначала для расчёта условий надо сначала все их прочитать
InFuz
Сообщение
#56687 21.4.2010, 12:17
Гляньте пожалуйста вроде должна работать, но чот ни фига не хочет
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
Сообщение
#56717 21.4.2010, 16:03
Есть много комментариев по 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
Сообщение
#56755 22.4.2010, 12:46
Все исправил, заработала.
Гляньте еще одну прогу.
Задание. Вычислить среднее значение элементов, расположенных в массиве между первым и последним нулевым значением. Поменять местами минимальный и максимальный элементы. Создать функции для определения среднего значения, макс. и мин.Код
# 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;
}