Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие2013_09_28.doc
Скачиваний:
24
Добавлен:
20.05.2015
Размер:
2.72 Mб
Скачать

2. Описание метода трапеций

Этот метод основан на том, что площадь криволинейной фигуры, ограниченной кривой y=f(x) и прямымиx=xi,x=xi+1иy=0, то есть интеграл, заменяется площадью прямоугольной трапеции с основаниями,и высотой

то есть

Тогда квадратурную формулу трапеций приближенного вычисления определенного интеграла Iможно записать в виде

Для достижения требуемой точности при вычислении по квадратурной формуле используется метод последовательного удвоения числа шагов. Для вычисления значения интеграла с заданной степенью точности необходимо первоначально принять некоторое произвольное количество разбиений участка интегрирования, например, n = 10 и вести расчет интеграла сначала при этом количестве разбиений, а затем при удвоенном, т.е. n = 20, затем при n = 40 и т.д. до тех пор, пока погрешность не станет меньше или равной заданной точности.

3. Программный комплекс

// integral.cpp Приближенное вычисление определенного

// интеграла методом трапеций

// Для достижения требуемой точности при вычислении по

// квадратурной формуле используется метод последовательного

// удвоения числа шагов n участка интегрирования.

#include "stdafx.h"

#include <conio.h>

#include <stdio.h>

#include <iostream>

using namespace std;

// вычисление 1 подынтегральной функции

double Fsqrt(double x)

{

return sqrt(2*x+1); // a = 0, b = 1 Ответ: 1.398717

}

// вычисление 2 подынтегральной функции

double Fsin(double x)

{

return sin(x/4); //a = 0, b = 1 Ответ: 0.124344

}

// вычисление 3 подынтегральной функции

double Fsqr (double x)

{

return x*x; //a = 0, b = 1 Ответ: 0.3333

}

// вычисление 4 подынтегральной функции

double f (double x)

{

return log(x); //a = 1, b = 2 Ответ:

}

// Функция вычисления интеграла методом трапеций

// В заголовке функции TRAP используется формальный параметр-указатель

// на функцию (*uf). При вызове этой функции в качестве фактического

// параметра ей передается имя реальной функции: Fsqrt, Fsin, Fsqr

// через оператор switch (num_F)

double trap(double a, double b, int n,double (*uf)(double))

{

int i; double h,s;

h=(b-a)/n; s=((*uf)(a)+(*uf)(b))/2;

for( i=1; i<= n-1; i++)

s=s+(*uf)(a+i*h);

s=s*h;

return s;

}

// основная программа

int main()

{ system("cls"); system("chcp 1251");

double a, b; // интервал интегрирования

double eps; // точность вычисления интеграла

double s1,s2; // последовательные приближения к интегралу

int n ; // число интервалов интегрирования

int num_F; // номер функции: 1,2,3

eps=0.00001 ; n=10;

//*******************************************

m2: cout<<"ВВЕДИ номер вызываемой функции: 1,2,3";

cin>>num_F;

if (num_F < 1 || num_F > 3)

{cout<<"ERROR num_F "; goto m2;}

cout<<"ВВЕДИ A "; cin>>a;

cout<<"ВВЕДИ B "; cin>>b;

//**********ВЫЗОВ ФУНКЦИИ TRAP*************

switch (num_F)

{

case 1: s1=trap(a,b,n,Fsqrt ); //вызов функции-метода

printf("n = %5d интеграл =%10.6lf\n", n, s1);

do

{ n=n*2; s2=trap(a,b,n,Fsqrt ); //вызов функции-метода

printf("n = %5d интеграл =%10.6lf\n", n, s2);

if(fabs(s2-s1)<eps)

break;

s1=s2;

}

while(1);

break; // для функции F1

case 2: s1=trap(a,b,n,Fsin ); //вызов функции-метода

printf("n = %5d интеграл =%10.6lf\n", n, s1);

do

{ n=n*2; s2=trap(a,b,n,Fsin ); //вызов функции-метода

printf("n = %5d интеграл =%10.6lf\n", n, s2);

if(fabs(s2-s1)<eps)

break;

s1=s2;

}

while(1);

break; // для функции F2

case 3: s1=trap(a,b,n,Fsqr ); //вызов функции-метода

printf("n = %5d интеграл =%10.6lf\n", n, s1);

do

{ n=n*2; s2=trap(a,b,n,Fsqr ); //вызов функции-метода

printf("n = %5d интеграл =%10.6lf\n", n, s2);

if(fabs(s2-s1)<eps)

break;

s1=s2;

}

while(1);

break; // для функции F3

}

return 0;

}

Далее следуют примеры программ, использующих функции и указатели.

Задача 148. Создать функцию, подсчитывающую сумму чисел, предшествующих первому отрицательному элементу в массиве.

// Программа отлажена в Visual Studio 2008 (27.05.2008)

#include<conio.h>

#include<stdio.h>

#include <iostream>

using namespace std;

// Сумма чисел до первого отрицательного

// элемента в массиве

float my_func(float *a, int n)

{ int flag = 0;

float s=0; float *uk1=a+n-1;

while( a <= uk1)

{ if( *a >= 0)

s=s + *a;

else

{ flag = 1; break;}

a++;

}

if(flag == 0)

return -777;

else

return s;

}

const int n = 7;

int main()

{ //float a[n]={2,4,6,88,9,10,15};

float a[n]={2,1,1,-1,1,1,1};

float s=my_func(a , n);

if (s < 0)

cout << "NOT FOUND\n";

else

cout<<s<<endl;

return 0;

}

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

// Программа отлажена в Visual Studio 2008

#include<conio.h>

#include<stdio.h>

#include <iostream>

using namespace std;

// Сумма чисел после последнего отрицательного

// элемента в массиве

float my_func(float *a, int n)

{ int flag = 0;

float s=0; float *uk1=a+n-1;

while( uk1 >= a)

{

if (*uk1 < 0)

{ flag = 1; break;}

uk1--;

}

if(flag == 0)

return -777;

else

{ uk1++;

while(uk1 < a + n)

{ s=s + *uk1; uk1++;}

return s;

}

}

const int n = 7;

int main()

{ //float a[n]={2,4,6,88,-9,10,15};

float a[n]={2,1,1,1,1,1,1};

float s=my_func(a , n);

if (s < 0)

cout << "NOT FOUND\n";

else

cout<<s<<endl;

return 0;

}

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

Функция dicho() рализует бинарный поиск, используя механизм указтелей и адресную арифметику для обработки массива. Ранее (см задачу 92) этот алгоритм был реализван в стиле традиционной обработки массивов с применением индексирования.

// Программа отлажена в Visual Studio 2008

#include<conio.h>

#include<stdio.h>

#include <iostream>

using namespace std;

//двоичный поиск 3.06.2008

int dicho(int *x, int n, int Q)

{

int low=0,high=n-1, mid, flag=0;

while(low <= high && !flag)

{

mid=(low+high)/2;

if(*(x+mid) == Q)

flag=1;

else

if(*(x+mid) < Q)

low=mid+1;

else

high=mid-1;

}

if(flag)

return mid;

else

return -777;

}

int main()

{

int i, Q,found;

int a[]={1,3,7,33,44,55,66,77,88};

int n=sizeof(a)/sizeof(int);

// Устанавливаем локализацию для выходного потока

wcout.imbue( locale( "rus_rus.866" ) );

// Выводим строку на русском !

wcout<< L"введи ключ поиска\n";

scanf("%d",&Q);

found = dicho(a, n, Q);

if(found>=0)

wcout<< Q<<L" на "<<found<<L" месте\n";

else

wcout<<Q<< L" не найден\n";

getch();

}

Вот результат работы этой программы:

введи ключ поиска

33

33 на 3 месте

Задача 151.Создать функцию, которая удаляет из заданной строки текст, заключенный в круглые скобки ( и ), формируя новую строку. Функция в случае успеха возвращает 0, и некоторое отрицательное число при неудаче (-1 при отсутствии “(“, -2 при отсутствии “)” ).

// Программа отлажена в Visual Studio 2005

#include<conio.h>

#include<stdio.h>

#include <iostream>

using namespace std;

// функция удаляет символы между ( и )

int del_skob(char *s1, char *s2)

{

while(*s1 != '\0' && *s1 != '(')

*s2++ = *s1++;

if(*s1=='\0')

return -1;

while(*s1 != '\0' && *s1 != ')')

s1++;

if(*s1=='\0')

return -2;

s1++;

while(*s1 != '\0' )

*s2++ = *s1++;

*s2=0;

return 0;

}

int main()

{

char s1[40]="12345(мама мыла раму)6789", s2[40];

int flag;

// Устанавливаем локализацию для выходного потока

wcout.imbue( locale( "rus_rus.866" ) );

// Выводим строку на русском !

wcout<< L"Введи строку "; gets(s1);

flag=del_skob(s1, s2);

if (flag==-1)

{wcout << L"Нет ("; getch();return 0;}

if (flag==-2)

{wcout << L"Нет )"; getch(); return 0;}

else

puts(s2);

getch();return 0;

}

Задача 152. Создать строку, содержащую цифры и другие символы. Определить функцию типа указатель, которая в динамической области памяти (“куче”) формирует новую строку на базе исходной, удалив предварительно из неё цифры и записав оставшиеся символы в обратном порядке. Функция должна возвращать указатель на вновь сформированную строку.

// Программа отлажена в Visual Studio 2008 (24.05.2008)

#include <iostream>

using namespace std;

char *delzifr(char *s);

int main ()

{

char *str="988776ASDFGH1233^%&^888";

// Устанавливаем локализацию для выходного потока

wcout.imbue( locale( "rus_rus.866" ) );

// Выводим строку на русском !

wcout<< L"Строка-результат: ";

cout<<delzifr(str)<<endl;

wcout<< L"Исходная строка: "<<str<<endl;

getch();return 0;

}

char *delzifr(char *s)

{

char *my_s= new char [strlen(s)];

// char *my_s=(char*)malloc(strlen(s));

char *uk1=s, *uk2=my_s;

while(*s)

s++; //End string

while(--s>=uk1)

{

if(*s<'0'|| *s>'9')

{

*my_s = *s;

my_s++;

}

}

*my_s ='\0';

return(uk2);

}

Задача 153. Определить строку в динамической области памяти. Подсчитать, сколько раз в заданную строку входит каждый её символ.

В приведенной ниже программе для подсчета числа вхождений каждого символа предусмотрена функция count(). Функция delchr() удаляет символ после подсчета количества его вхождений в строку.

// count2.cpp Программа отлажена в Visual Studio 2008

#include "stdafx.h"

#include<conio.h>

#include<stdio.h>

#include <iostream>

using namespace std;

void delchr(char *, char); // прототип функции

// Подсчет числа вхождений каждого символа

void count(char *s)

{

char *uk, ch; int k;

while((ch = *s)!='\0')

{

//указатель S не сдвигается!

k=1; uk=s+1;

while(*uk != '\0')

{

if(ch==*uk)

k++;

uk++;

}

//printf("%c - %d \n",ch,k);

wcout <<L"символ "<<ch<<L" встречается "<<k<<L" раз\n";

delchr(s,ch);

}

}

// удаление символа в строке

void delchr(char *s,char c)

{

char *uk=s;

while(*s!='\0')

{

if (*s!=c)

{

*uk=*s;

uk++;

}

s++;

}

*uk='\0';

}

int main()

{

char *s; int size;

wcout.imbue( locale( "rus_rus.866" ) );

wcout<< L"Укажи длину строки :";

cin>>size; fflush(stdin);

s=(char*)malloc(size);

wcout<< L"Введи строку "; gets(s);

count(s);

getch();return 0;

}

Задача 154. Создать функцию, которая находит в заданной строке последнее вхождение символа # и пересылает в другую строку символы, начиная с найденного символа и до конца строки. Если искомый символ не найден, функция возвращает -1, иначе – номер позиции найденного символа в исходной строке.

/ Программа отлажена в Visual Studio 2008

#include<conio.h>

#include<stdio.h>

#include <iostream>

using namespace std;

int move_str (char *s1, char *s2)

{

char *uks = s1;

while (*uks)

uks++;

uks--;

while (uks >=s1 && *uks != '#')

uks--;

char *k = uks;

if (uks < s1)

return -1;

else

while (*uks != '\0')

*s2++ = *uks++;

*s2 = 0;

return (k - s1); //позиция символа #

}

int main()

{ char s1[]="12345# 6789# END", s2[25];

int k = move_str(s1,s2);

if (k < 0)

puts("# NOT FOUND");

else

{puts(s2); cout << endl<<k;}

return 0;

}

Задача 155. Определить строку в динамической области памяти. Создать функцию delsub( str, k, L ) для удаления из заданной строки str подстроки длиной L символов, начиная из символа с номером k.

// Программа отлажена в Visual Studio 2008

#include <stdlib.h>

#include <malloc.h>

#include<conio.h>

#include<stdio.h>

#include <iostream>

using namespace std;

// функция удаления подстроки

void delsub(char *s, int k, int l)

{

char *uk;

if(k>strlen(s)) return;

if(k+l>=strlen(s))

{ *(s+k)='\0';

return;

}

s=s+k; uk=s+l;

while(*s++ = *uk++) // копирование

;

//или так: for(s=s+k,uk=s+l; (*s=*uk); s++,uk++) ;

}

int main()

{

int k,l;

int size;

// Устанавливаем локализацию для выходного потока

wcout.imbue( locale( "rus_rus.866" ) );

// Выводим строку на русском !

wcout<<L"Укажи длину строки :";

cin>>size; fflush(stdin);

//char *s =(char*)malloc(size);

char *s = new char [size];

wcout<<L"Введи строку "; gets(s);

wcout<<L"Введи k и l ";

cin>>k>>l;

delsub(s,k,l);

puts(s);

getch();return 0;

}

Задача 156. Проверить, можно ли из букв, входящих в заданное слово (А), составить другое заданное слово (В). Каждая буква исходного слова может быть использована в формируемом слове только один раз.

Приведенная ниже программа использует две функции: slova() и del(). Первая из них осуществяет собственно проверку, входит ли каждая буква слова А в слово В. Вторая функция удаляет протестированную букву из слова А. Обратите внимание на тонкий момент: функция slova() работает с переменной flag, которая учитывает удаление последнего символа слова А, на который функция del() пересылает нуль-символ ('\0').

// Программа отлажена вVisual Studio 2008

#define L 80

#include <stdio.h>

#include <conio.h>

#include <iostream>

using namespace std;

void del(char *s,char c)

{

char *uk=s;

while (*s)

{

if(*s != c)

*uk++=*s;

s++;

}

*uk='\0';

}

int slova(char *A,char *B)

{ char *uk=A;int flag;

while (*B)

{ A=uk;

putchar(*B);putchar('\n');

flag=0;

while (*A)

{

if(*A==*B)

{ del(A,*A); //*A='*';

flag=1;

puts(uk);

break;

}

A++;

}

if(*A=='\0' && flag==0)

return 0;

B++;

}

return 1;

}

int main()

{

char A[L]="интеграл", B[L]="гантели";

// Устанавливаем локализацию для выходного потока

wcout.imbue( locale( "rus_rus.866" ) );

// Выводим строку на русском !

wcout<< L"Введи слово А "; cin >> A;

wcout<< L"Введи слово B "; cin >> B;

if(slova(A,B))

wcout<< L"можно";

else

wcout<< L"нельзя";

getch();return 0;

}

Задача 157. В заданной строке символов содержатся буквы, цифры и, быть может, некоторые другие символы. Создать функцию, которая выделяет из заданной строки только цифры и образует из них натуральное число типа unsigned long, которое и является возвращаемым функцией значением. Считать, что в строке содержится не более 9 цифр. Для обработки текста использовать указатели.

// Программа отлажена в Visual Studio 2008

#include<stdio.h>

#include<conio.h>

#include <iostream>

using namespace std;

unsigned long str_to_numb(char *s)

{

unsigned long m=0; int kzifr=0;

while(*s)

{ if(*s>='0' && *s<='9')

{ m=m*10+(*s-'0');

kzifr++;

}

if(kzifr >= 10)

{

printf("VERY MANY FIGURES - ");

return kzifr;

}

s++;

}

return m;

}

int main()

{

unsigned long m=0;char s[32]="75ee109wfg639()E";

m=str_to_numb(s);

printf("%ld\n",m);

getch(); return 0;

}

Задача 158.Создать функцию, которая заданную строку S1[L], каждый символ которой - двоичная цифра ('0', '1'), преобразует в эквивалентное десятичное число типа unsigned long int, которое и является возвращаемым функцией значением. Длина строки не превышает 32.

// str_num.cpp Программа отлажена в Visual Studio 2008

#include<conio.h>

#include<stdio.h>

#include <iostream>

using namespace std;

unsigned long str_to_number(char *str)

{

unsigned int maska=1;

unsigned long m=0;

char *uk=str;

while(*uk) uk++;

while(--uk>=str)

{

m=m + (*uk-'0')*maska;

maska<<=1;

}

return m;

}

int main()

{

char str[33]="01111111111111111111111111111111";

unsigned long m = str_to_number(str);

printf("%ld",m);

getch(); return 0;

}

Задача 159. Составить программу, которая определяет массив строк poem[4][60] следующего содержания:

Едва увидел я сей свет,

Уже зубами смерть скрежещет,

Как молнией, косою блещет

И дни мои, как злак, сечет.

(Державин)

Определить две функции, которые позволяют:

а) найти и выдать на экран слова, в которые заданная буква "е" входит два и более раз;

б) перевернуть все слова, которые начинаются заданной буквой "с".

Использовать указатели при обработке текста.

// Программа отлажена в Visual Studio 2008

#include "stdafx.h"

#include<conio.h>

#include<stdio.h>

#include <iostream>

using namespace std;

// Буква "e" или "E" входит 2 и более раз?

void two_raz( char *s, char ch1, char ch2 )

{

int m; char *uk1,*uk2;

uk1 = s;

while(*uk1!='\0')

{

while(*uk1 == ' ')

uk1++;

uk2 = uk1; m = 0;

while (*uk1 != ' ' && *uk1 != '\0')

{

if(*uk1==ch1 || *uk1==ch2)

m++;

uk1++;

}

if(m>=2)

while(uk2<uk1)

{

putchar(*uk2);

uk2++;

}

putchar(' ');

}

}

//перевернуть слово на заданную букву

void revers(char *s, char ch)

{

char *uk1,*uk2, r;

while(*s)

{

// пропуск пробелов перед словом

while(*s==' ')

s++;

uk1=s; // указатель на начало слова

// пропуск слова

while(*s != ' ' && *s != '\0')

s++;

uk2=s-1; // указатель на конец слова

if(*uk1 == ch)

while(uk2 > uk1)

{

r=*uk2;

*uk2=*uk1;

*uk1=r;

uk1++;uk2--;

}

}

}

#define L 80

int main()

{

char poem[4][L]={

" Едва увидел я сей свет,",

" Уже зубами смерть скрежещет",

" Как моленией, косою блещет",

" И дни мои, как злак, сечет."

};

// а)

char bukwa_e = 'е', bukwa_E = 'Е';

for(int k=0; k<4; k++)

{

two_raz(poem[k], bukwa_e, bukwa_E );

putchar('\n');

}

// б)

char bukwa_c = 'с';

for(int k=0; k<4; k++)

{

revers(poem[k], bukwa_c );

puts(poem[k]);

}

getch();return 0;

}