Смекни!
smekni.com

Язык прораммирования С++ (стр. 7 из 7)

Вывести элементы двумерного массива на экран можно различными способами.

Удобно организовать цикл по строкам и вложить в него цикл по столбцам

for(int i=0; i<3;i=i+1)

for (j=0;j<4;j=j+1) printf (“%5d”,Mas[i][j]);.

Можно также учесть, что в массиве 12 чисел и сделать цикл от нуля до 12, но при этом придется использовать новую арифметическую операцию % (получение остатка от деления целых чисел)

for(inti=0; i<12;i=i+1) printf (“%5d”,Mas[i/4][i%4]);.

Оба приведенные выше цикла будут печатать элементы массива в одну строку.

Если мы хотим выводить массив в виде прямоугольной таблицы, перед каждой следующей строкой (или после каждой строки) массива надо вывести на экран символ перевода курсора &bsol;n., как показано ниже:

for(int i=0; i<3;i=i+1)

{

for (j=0;j<4;j=j+1) printf (“%5d”,Mas[i][j]);.

printf(“&bsol;n”);

}

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

Помню, в школе нас учили решать алгебраические уравнения методом подстановки и методом алгебраического сложения. В ВУЗе в курсе алгебры мы узнаем, что решение систем линейных уравнений школьным методом алгебраического сложения называется методом Гаусса, а также знакомимся с алгоритмами вычисления определителя и обратной матрицы. Они основаны на последовательности шагов, заключающихся в умножении элементов строки на константу и прибавлении к соответствующим элементам другой строки то же матрицы.

Составим, для примера, программу решения систем уравнений методом Гаусса и решим систему:

1.7x1 + 10.0x2 - 1.3x3 + 2.1x4 = 3.1

3.1x1 + 1.7x2 - 2.1x3 + 5.4x4 = 2.1

3.3x1 - 7.7x2 + 4.4x3 - 5.1x4 = 1.9

10.0x1 - 20.1x2 + 20.4x3 + 1.7x4 = 1.8

При решении системы все ее числовые коэффициенты можно хранить в массиве, объявленном как doublea[4][5]. Столбец свободных членов системы – это элементы a[I][4], где I=0,..., 3.

Методом Гаусса основано на последовательности преобразований системы, не изменяющих ее корней.

Если прибавить к левой и правой части уравнения одно и то же число, его корни не изменяются. (Когда x1x2 …xn– это корни уравнения, его левая и правая части равны. Поэтому к одном уравнению можно, не изменяя корней, прибавить другое, умноженное на числовой коэффициент).

В методе Гаусса решение системы из n уравнений получается за n шагов.

На шаге номер k:

уравнение номер k делится на коэффициент a[k][k] – диагональный элемент матрицы становится равным единице;

потом (для всех i ≠ k) к уравнению номер i прибавляется уравнение номер k умноженное на минус a[i][k]. В результате в столбце k все коэффициенты, кроме расположенного на диагонали, станут равными нулю (для ручного счета указанные на данном шаге действия выполняются только для значений i>k, но нам удобнее заменить нулями все коэффициенты столбца, кроме одного).

После того, как циклом, изменяющим k от нуля до n-1 выполнится n описанных выше шагов, в каждой строке коэффициенты при всех неизвестных, кроме одного, будут равны нулю – это и есть решение.

Проделаем описанные преобразования для заданного уравнения.

Разделим все коэффициенты первой строки на a[0][0]=1.7. Первое уравнение приобретет вид:

x1 + 5.882x2 - 0.7647x3 + 1.235x4 = 1.824

Теперь, чтобы в уравнении 2 получить нулевой коэффициент при x1, все элементы первого уравнения умножаем на a[1][0]=3.1 и отнимаем от второго, получим

0x1 - 16.54 x2 + 0.2706 x3 + 1.571 x4 = 3.553

и так далее.

Программа, реализующая данный алгоритм, оказывается заметно короче его описания:

#include<stdio.h>

#include<conio.h>

doublea[4][5]={{1.7, 10.0, -1.3, 2.1, 3.1}, //Записали систему уравнений

{1, 1.7, -2.1, 5.4, 2.1},

{3.3, -7.7, 4.4, -5.1, 1.9},

{10.0,-20.1, 20.4, 1.7, 1.8}};

voidprint (void) //Вывод таблицы коэффициентов оформили в виде функции.

{ for(int i=0;i<4;i++){for(int j=0;j<5;j++)

printf("%8.4lg ",a[i][j]);printf("&bsol;n");}

printf("&bsol;n");

}

void main (void)

{

clrscr();

print(); //Вывели исходную таблицу

for(intk=0;k<4;k++) //Цикл по числу уравнений

{ double Kf=a[k][k];

for(int j=0;j<5;j++) a[k][j]=a[k][j]/Kf; //Получаемединицуприxk

for(inti=0;i<4;i++)

{ //Во всех уравнениях, кроме k-го делаем коэффициент при xk равным нулю.

Kf=a[i][k];

if(i!=k) for(j=0;j<5;j++) a[i][j]=a[i][j]-a[k][j]*Kf;

}

print();//Вывели таблицусо столбцом из нулей.

}

getch();

}

В приведенной программе делитель a[k][k]; предварительно записывается в отдельную переменную: Kf=a[k][k];.

Объясните, почему нельзя отказаться от использования промежуточной переменной Kf, записав вместо оператора a[k][j]=a[k][j]/Kf; оператор a[k][j]=a[k][j]/ a[k][k];.

Далее показаны результаты вывода на экран.

Исходная таблица

1.7 10 -1.3 2.1 3.1

3.1 1.7 -2.1 5.4 2.1

3.3 -7.7 4.4 -5.1 1.9

10 -20.1 20.4 1.7 1.8

Результат обработки при k=0 (сравните с ручным счетом)

1 5.882 -0.7647 1.235 1.824

0 -16.54 0.2706 1.571 -3.553

0 -27.11 6.924 -9.176 -4.118

0 -78.92 28.05 -10.65 -16.44

Результат обработки при k=1

1 0 -0.6684 1.794 0.5596

-0 1 -0.01636 -0.09498 0.2149

0 0 6.48 -11.75 1.708

0 0 26.76 -18.15 0.523

Результат обработки при k=2

1 0 0 0.5818 0.7358

0 1 0 -0.1247 0.2192

0 0 1 -1.814 0.2636

0 0 0 30.37 -6.529

Результат обработки при k=3

1 0 0 0 0.8608

0 1 0 0 0.1924

0 0 1 0 -0.1263

0 0 0 1 -0.215

Проверьте, что подстановка в уравнения значений x0=0.8608, x1=0.1924,

x2=-0.1263, x3=-0. 215 дает тождества.

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

Заметим, что программа завершится аварийно, если в исходной системе на главной диагонали будет нулевой элемент.

Чтобы этого не случилось можно переставить уравнения местами.

Пример программы, реализующей модификацию данного алгоритма нечувствительную к нулевым элементам (метод Жордана-Гаусса находится на диске в папке JrdGauss, в тексте учебника мы его разберем при знакомстве с оконным интерфейсом ОС Windows).