
- •Тема 1. Основные этапы решения задач на эвм 5
- •Тема 2. Жизненный цикл программы. Критерии качества программы. 15
- •Тема 3. Схемы алгоритмов, данных, программ 29
- •Тема 1. Основные этапы решения задач на эвм Постановка задачи разработки программного обеспечения
- •Анализ формальной постановки задачи
- •Выбор или разработка математической модели и метода решения
- •Разработка алгоритма
- •Базовые структуры алгоритма
- •3.2. Цикл с постусловием.
- •Тема 2. Жизненный цикл программы. Критерии качества программы.
- •Техническое задание и спецификация программы
- •Разработка проекта программной системы
- •Программирование (кодирование) или программная реализация алгоритмов
- •Тестирование и отладка
- •Эксплуатация и сопровождение
- •Критерии качества программного обеспечения
- •Тема 3. Схемы алгоритмов, данных, программ
- •Символы данных
- •Отображает данные, вводимые в ручную, во время обработки с устройств любого типа (клавиатура, переключатели, кнопки, световое перо, полоски со штрих кодом и т.Д.).
- •Символы процесса
- •Символы линий
- •Специальные символы
- •Правила применения символов в схемах
- •Правила выполнения соединений
- •Специальные условные обозначения
- •Тема 4. Язык программирования высокого уровня Си Общие сведения о языке Си
- •Алфавит языка Си
- •Грамматика для описания языка, синтаксические диаграммы
- •Структура программы на языке Си
- •Void main() //функция main
- •Имена объектов в программе
- •Выражения, операции и приоритеты
- •Тема 5. Стандартные типы данных
- •Тема 6. Составные типы данных Данные регулярного типа (массивы)
- •Int b [n]; // вектор из 10 целых элементов
- •9 Strcpy(s1,&s2[k]); //копирует правую подстроку из s2 в s1
- •9 Strncpy(s1,&s[2],n); //копирует среднюю подстроку из s2 в s1
- •Void main() /*пример функции*/
- •If(strcmp(s, "пароль"))
- •If(!strсmp("quit", s)) break;
- •Данные комбинированного типа (структуры)
- •Int month;
- •Int year;
- •Перечисления
- •Объединения
- •Указатели
- •Void *addres;
- •Int arrey[25];
- •Тема 7. Представление основных управляющих структур программирования Оператор присваивания
- •Составной оператор
- •Оператор перехода Goto
- •Условный оператор If
- •Оператор выбора switch
- •Операторы цикла while, do – while, for
- •Int I,j,imax,jmax,imin,jmin;
- •Операторы прерывания циклов
- •If (!flag) printf("Отрицательных чисел нет"); Форматированный ввод данных
- •Форматированный вывод данных
- •Преобразование типов
- •Инициализация данных
- •Тема 8. Функции
- •Определение функций в языке Си
- •Int rus (unsigned char r)
- •Void change (int X, int y)
- •Void change (int *X, int *y)
- •Вызов функций в языке Си
- •Int *fun (intx,int *y);
- •Int main()
- •Рекурсивные функции
- •Int nodWhile (int m, int n)
- •Int nodWhile (int m, int n)
- •Int main()
- •Int fCalculated[nFib];
- •Int FibDinam (int n)
- •Int main()
- •Int Summa(int n, int a[100])
- •Int main()
- •Тема 9. Файлы
- •Int fseek(file *fp, long count, int access);
- •Int ferror(file *fp);
- •Int remove(char *file_name);
- •Void rewind(file *fp);
- •Int main()
- •Тема 10. Приемы программирования. Примеры алгоритмов Алгоритмы сортировки
- •Исходный массив
- •Void SortBubble (int count, int* pArr)
- •Исходный массив
- •Void SortSelect(int count, int* pArr)
- •Int i1,temp;
- •Int jmax;
- •Void SortInsert (int count, int* pArr)
- •Int temp, j;
- •Алгоритмы поиска
- •Int bfSearch(char *s, char *p)
- •Int bmtarr[255];
- •Int bmSearch(int startpos, char *s, char *p)
- •Int BinarySearch (int lb, int ub, int key, int* pArr)
- •Динамические структуры данных
- •Линейные списки
- •Int value; // значение элемента
- •Void PrintSearchList (list head, int val)
- •If (lfound) printf("Элемент в списке найден!");
- •Стек, очередь, дек
- •Int prior(char);
- •Void main(void)
- •Int k, point;
- •Int prior(char a)
- •Деревья
- •Int info; //информационное поле
- •Приложение 1. Стандартные библиотеки языка Си
- •Приложение 2. Примеры реализации алгоритмов
- •Int main()
- •Int arr[10]; // Массив arr из 10 целочисленных элементов
- •Int I; // Счетчик для циклов
- •Int main()
- •Int main()
- •Int main()
- •Int Temp;
- •Int CurrentYear, Diff, Day1, Day2, Month1, Month2, I, Visokos;
- •Int main()
- •InsertSort(d, max); // Сортируем массив b методом вставок
- •Int number;
- •Int main()
- •Не рекурсивный алгоритм решения задачи Ханойская башня.
- •Int main()
- •Рекурсивный алгоритм решения задачи Ханойская башня.
- •Void move(int I, int j, int d)
- •Void hanoy(int I, int j, int k, int d)
- •Int main()
- •Int Cubic(double *X,double a,double b,double c);
- •Int Cubic (double *X, double a, double b, double c)
- •Void lu_backsub (double **a, int n, int *indx, double *b)
- •Void lu_invert (double **a, int n, int *indx, double **inv, double *col)
- •Int BracketRoot (double x0, double *a, double *b, double d0, double di, double dmax, double (*fun)(double));
- •Int BracketRoot (double x0, double *a, double *b, double d0,
- •Int main()
- •Int expo, I;
- •If (expo & 1)
- •Int main()
- •Приложение 3. Лабораторные работы Лабораторная работа №1
- •Лабораторная работа №2
- •Лабораторная работа №3
- •Лабораторная работа №4
- •Лабораторная работа №5
- •Лабораторная работа №6
- •Лабораторная работа №7
- •Лабораторная работа №8
- •Лабораторная работа №9
- •Лабораторная работа №10
- •Лабораторная работа №11
- •Лабораторная работа №12
- •Список литературы
Int Cubic (double *X, double a, double b, double c)
{
double q, r, r2, q3;
q = (a * a - 3. * b) / 9.;
r = (a * (2. * a * a - 9. * b) + 27.*c) / 54.;
r2 = r * r;
q3 = q * q * q;
if (r2 < q3)
{
double t = acos(r / sqrt (q3));
a /= 3.;
q = -2. * sqrt (q);
x[0] = q * cos (t / 3.) - a;
x[1] = q * cos ((t + M_2PI) / 3.) - a;
x[2] = q * cos ((t - M_2PI) / 3.) - a;
return (3);
}
else
{
double aa, bb;
if (r <= 0.) r =- r;
aa = -pow (r + sqrt (r2 - q3), 1. / 3.);
if(aa != 0.) bb = q / aa;
else bb = 0.;
a /= 3.;
q = aa + bb;
r = aa - bb;
x[0] = q - a;
x[1] = (-0.5) * q - a;
x[2] = (sqrt (3.) * 0.5) * fabs (r);
if (x[2] == 0.) return (2);
return (1);
}
}
Пример 14. Алгоритм Краута (нижне-верхняя (LU) декомпозиция матрицы).
Алгоритм Краута это фактически метод решения систем общего вида, конкурирующий по быстродействию с общеизвестным методом Гаусса-Жордана, но позволяющий более эффективно использовать решение.
Если мы можем разложить матрицу линейной системы A в произведение A=L*U, где L нижняя, а U верхняя треугольные матрицы, то решение системы уравнений с произвольной правой частью производится весьма просто, применением двух обратных подстановок. Более того, в отличие от известного метода Гаусса-Жордана, разложенная матрица позволяет быстро решать серии линейных уравнений с различными правыми частями при одной и той же матрице.
Метод Краута позволяет провести LU-декомпозицию матрицы примерно за то же число операций, что и "прямая" часть метода Гаусса-Жордана. Итоговые коэффициенты двух треугольных матриц упаковываются в матрицу того же размера, что и A, и на том же месте в памяти; при этом верхняя матрица U размещается в наддиагональной части и на диагонали; нижняя L в поддиагональной части, а диагональные элементы L считаются все равными 1 (без ограничения общности) и не выводятся.
Алгоритм Краута представляет из себя следующее:
-
Положить Lii=1 i=0,...,N-1 (здесь ничего не производится, а только имеется в виду для дальнейших шагов;
-
Для каждого j=0,1,...,N-1 проделать:
-
Для всех i=0,...,j вычислить Uij:
Uij=Aij - SUM(0<=k<i)(Lik*Uik) (при i=0 сумму полагать нулем);
-
Для всех i=j+1,...,N-1 вычислить:
Lij = Aij - SUM(0<=k<j)(Lik*Uik))/Uii
Обе процедуры выполняются до перехода к новому j.
Устойчивая работа алгоритма Краута возможно только при условии выбора ведущего элемента для каждого обращения к j из п.2 алгоритма. Выбор производится перед выполнением п.2 для очередного j перестановки необработанных строк матрицы так, чтобы строка, подставляемая на место j, содержала наибольший по модулю элемент в колонке j. Порядок перестановки необходимо запомнить, для чего достаточно использовать дополнительный вектор целых величин. Еще один вектор используется внутри алгоритма для масштабирования.
Алгоритм Краута имеет несколько приложений, одно из которых решение системы линейных уравнений (обратная подстановка с учетом порядка перестановки строк), другие вычисление обратной матрицы и вычисление детерминанта. Подробнее вызовы функций, связанных с алгоритмом Краута и реализация деталей алгоритма находятся в комментариях к программе и в ней самой.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <string.h>
#define TINY 1.e-30
/*
LU-декомпозиция в соответствии с алгоритмом Краута.
Описание:
int LU_decompos(double **a,int n,int *indx,int *d,double *vv);
Параметры:
a - исходная матрица (n x n) на входе;
n - размер матрицы;
indx - массив целых чисел (размера n) для запоминания перемещений;
d - на выходе, содержит +1 или -1 для четного или нечетного числа перемещений.
vv - временный массив (size n).
Результат:
0 - некорректная входная матрица (непригодна для декомпозиции),
1 - положительный результат.
Обратная замена, использующая LU-декомпозицию матрицы.
Описание:
void LU_backsub(double **a,int n,int *indx,double *b);
Параметры:
a - матрица, разложенная по Крауту;
n - размер матрицы;
indx - порядок перемещения, полученный алгоритмом декомпозиции;
b - вектор (размера n).
Примечание: a и indx не изменяются в этой функции и могут быть использованы повторно.
Инвертирование матрицы с использованием LU-разложенной матрицы.
Описание:
void LU_invert(double **a,int n,int *indx,double **inv,double *col);
Параметры:
a - матрица, разложенная по Крауту;
n - размер матрицы;
indx - порядок перестановки, полученный алгоритмом декомпозиции;
inv - матрица назначения;
col - временный массив (размера n).
Получение матрицы, полученной с использованием LU-разложенной матрицы
Описание:
double LU_determ(double **a,int n,int *indx,int *d);
Параметры:
a - матрица, разложенная по Крауту;
n - размер матрицы;
indx - порядок перемещения, полученный алгоритмом декомпозиции;
d - знак равенства (+1 или -1) полученный при декомпозиции.
Результат: определяющее значение.
*/
/* декомпозиция */
int LU_decompos (double **a, int n, int *indx, int *d, double *vv)
{
register int i, imax, j, k;
double big, sum, temp;
for (i = 0; i < n; i++)
{
big = 0.;
for (j = 0; j < n; j++)
if ((temp = fabs (a[i][j])) > big) big = temp;
if (big == 0.) return (0);
vv[i] = big;
}
/* главный цикл алгоритма Краута */
for (j = 0; j < n; j++)
{ /* это часть a) алгоритма, исключая i==j */
for (i = 0; i < j; i++)
{
sum = a[i][j];
for (k = 0; k < i; k++) sum -= a[i][k] * a[k][j];
a[i][j] = sum;
}
/* инициализация для поиска наибольшего элемента */
big = 0.;
imax = j;
for (i = j; i < n; i++)
{
sum = a[i][j];
for (k = 0; k < j; k++) sum -= a[i][k] * a[k][j];
a[i][j] = sum;
if ((temp = vv[i] * fabs (sum)) >= big)
{
big = temp;
imax = i;
}
}
/* обмен строк, если нужен, смена равенства и размера множителя */
if (imax != j)
{
for (k = 0; k < n; k++)
{
temp = a[imax][k];
a[imax][k] = a[j][k];
a[j][k] = temp;
}
*d =- (*d);
vv[imax] = vv[j];
}
/* сохраняем индекс */
indx[j] = imax;
if (a[j][j] == 0.) a[j][j] = TINY;
if (j < n - 1)
{
temp = 1. / a[j][j];
for (i = j+1; i < n; i++) a[i][j] *= temp;
}
}
return (1);
}
/* обратная замена */