Форум программистов, компьютерный форум, киберфорум
Java для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/64: Рейтинг темы: голосов - 64, средняя оценка - 4.73
0 / 0 / 0
Регистрация: 11.10.2012
Сообщений: 34

Метод Крылова (нахождение собственных значений матрицы)

07.06.2014, 07:31. Показов 12793. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Народ, вот ниже приведен исходник на С++ метода Крылова, который находит собственные значения матрицы размерностью 4х4. Беда в том, что надо перевести на Java, очень срочно! помогите


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#include <iostream>
#include <math.h>
//Объявим прототипы процедур и функций
void dispArr (float **Arr, int i, int j, char t[7]);
float** arrMult (float **Arr, float **ArrO, int m, int n, int q);
float** treugArr (float **Arr, int n);
float* gSolve (float **Arr, int n);
float halfDiv(float *P, float eps);
float* urDiv (float *P, float a, int n);
float urTest4 (float a, float b, float *P);
 
float** arrMult (float **Arr, float **ArrO, int m, int n, int q) //Функция перемножения матриц
{
    float **MultArr;
    //Динамически создаем матрицу - результат произведения
    MultArr = new float*[m];
    for (int i=0; i<m; i++) 
    { 
        MultArr[i] = new float[q]; 
    };
    //Вычисляем произведение матриц
    for (int i=0; i<m; i++)
        for (int j=0; j<q; j++)
        {
            MultArr[i][j] = 0;
            for (int k=0; k<n; k++)
                MultArr[i][j] += Arr[i][k]*ArrO[k][j];
        }
    return MultArr;
}
 
float** treugArr (float **Arr, int n) //Приведение матрицы к треугольному виду
{
    //Приводим матрицу A к треугольному виду
    for (int i=0; i<n; i++)
    {
        //Обнуляем необходимые элементы
        for (int j=i+1; j<n; j++)
        {
            float koeff = Arr[j][i]/Arr[i][i]; //Коэффициент, на который будем домножать строку
            for (int k=0; k<n+1; k++)
                Arr[j][k]=Arr[j][k]-Arr[i][k]*koeff;
        }
    }
    return Arr;
}
 
float* gSolve (float **Arr, int n) //Нахождение переменных в матрице, приведенной к треугольному виду
{
    float *X;
    X = new float[n];
    //Расчет неизвестных:
    X[3] = Arr[3][4]/Arr[3][3];
    X[2] = (Arr[2][4] - Arr[2][3]*X[3])/Arr[2][2];
    X[1] = (Arr[1][4] - Arr[1][2]*X[2] - Arr[1][3]*X[3])/Arr[1][1];
    X[0] = (Arr[0][4] - Arr[0][1]*X[1] - Arr[0][2]*X[2] - Arr[0][3]*X[3])/Arr[0][0];
    
    return X;
}
 
float halfDiv(float *P, float eps) //Метод половинного деления
{
    float a=0, b=0, prec;
    
    do {
        a--; b++;
    } while (urTest4(a, b, P) > 0);
    std::cout << "Исходный отрезок для нахождения корней: ";
    std::cout << "[" << a << "," << b << "]\n";
    do
    {
        prec = b - a;
        float cent = (a+b)/2;
        if (urTest4(a, cent, P) < 0) b=cent;
        else a=cent;
    } while (prec>eps);
    
    return a;
}
 
float* urDiv (float *P, float a, int n) //Деление уравнения
{
    P[n]=0;
    for (int i=n-1; i>=0; i--)
    {
        if (i+1 == n)
            P[i]=-P[i]+a;
        else
            P[i]=-P[i]+P[i+1]*a;
    }
    for (int i=0; i<n; i++)
        if (i+1 == n)
            P[i] = -1;
        else
            P[i] = -P[i+1];
 
    return P; 
}
 
float urTest4 (float a, float b, float *P) //Проверка знаков на концах отрезка
{
    float r1 = P[4]*pow(a, 4) - P[3]*pow(a, 3) - P[2]*pow(a,2) - P[1]*a - P[0];
    float r2 = P[4]*pow(b, 4) - P[3]*pow(b, 3) - P[2]*pow(b,2) - P[1]*b - P[0];
    
    return r1*r2;
}
 
void dispArr (float **Arr, int si, int sj, char t[7]) //Процедура отображения матрицы
{
    std::cout << "------------------------------ \n";
    for (int i=0; i<si; i++)
    {
        for (int j=0; j<sj; j++)
            printf(t, Arr[i][j]);
        std::cout << "\n";
    }
    std::cout << "------------------------------ \n";
    
}
 
int main (int argc, const char * argv[])
{
 
    FILE *file;
    float kf, eps, a;
    float **A, **B, **C, **mC, **c0, *P, *lambda, **tmpArr;
    int ni, nj, i, j;
    //Открываем файл для чтения исходных данных
    file = fopen("/Volumes/Macintosh HD/Users/nick_ny/Study/Chisl_method/Lab4_Krylov/Lab4_Krylov/input.txt", "r");
    //Считываем из файла размерность массивов Ni x Nj
    fscanf(file, "%d", &ni); fscanf(file, "%d", &nj);
    //Создаем динамические массивы
    A = new float*[ni]; B = new float*[ni]; C = new float*[ni];
 
    for (int i=0; i<ni; i++) 
    { 
        A[i] = new float[nj]; 
        B[i] = new float[nj]; 
        C[i] = new float[nj];
    };
    
    //Считываем массив B:
    for (i=0; i<ni; i++)
        for (j=0; j<nj; j++)
            fscanf(file, "%f ", &B[i][j]);
    //Считываем массив C:
    for (i=0; i<ni; i++)
        for (j=0; j<nj; j++)
            fscanf(file, "%f ", &C[i][j]);
    //Считываем число k:
    fscanf(file, "%f", &kf);
    //Считываем желаемую точность
    fscanf(file, "%f", &eps);
    fclose(file);
    //Формируем массив A, с которым будем работать (A = B + kC):
    for (i=0; i<ni; i++)
        for (j=0; j<nj; j++)
        { 
            A[i][j] = B[i][j] + kf*C[i][j];
        }
    std::cout << "Исходная матрица A:\n";
    dispArr(A, ni, nj, "%5.2f ");
//Блок нахождения значений C(0), C(1), C(2), C(3), C(4)
    //Создадим массив который будет хранить эти значения
    mC = new float*[ni];
    for (int i=0; i<ni; i++) 
        mC[i] = new float[ni+1];
    //В этом массиве за C(0) примем (1, 1, 1, 1)
    for (int i=0; i<ni; i++) 
        mC[i][0] = 1;
    //Создадим массив c0, который будет хранить текущее значение C(1), C(2), C(3), C(4)
    c0 = new float*[ni];
    for (int i=0; i<ni; i++) 
        c0[i] = new float[1];
    //Перейдем к нахождению C(1), C(2), C(3), C(4)
    for (int i=0; i<ni; i++)
    {
        //Заполним массив c0 текущим значением - C(i)
        for (int j=0; j<ni; j++)
            c0[j][0]=mC[j][i];
        //Для нахождения C(i+1) умножим массив A на с0
        tmpArr = arrMult(A, c0, ni, nj, 1);
        //Занесем полученные данные в массив mC
        for (int j=0; j<ni; j++)
            mC[j][i+1]=tmpArr[j][0];
    }
    std::cout << "   C(0)    C(1)    C(2)    C(3)   C(4) \n";
    dispArr(mC, 4, 5, "%7.3f ");
//Запишем систему уравнений для нахождения P1, P2, P3, P4    
    treugArr(mC, 4);
    P = new float[ni+1];
    P = gSolve(mC, 5);
    P[4] = 1;
//Запишем получившееся уравнение с λ
    std::cout << "Характеристическое уравнение: \n";
    std::cout << P[4] << " λ^4 - (" << P[3] <<") λ^3 - (" << P[2] << ") λ^2 - (" << P[1] << ") λ - (" << P[0] <<") = 0 \n";
    lambda = new float[ni];
//Ищем значения λ методом половинного деления     
    for (int k=4; k>0; k--)
    {
        //Будем решать полученное уравнение методом половинного деления    
        a = halfDiv(P, eps);
        lambda[k-1] = a;
        std::cout << "λ[" << ni+1-k << "]: ";
        printf("%7.3f \n", a);
        //Разделим уравнение на полученный корень, чтобы получить кубическое
        P = urDiv(P, a, k);
        //Запишем результат деления
        if (k-1 > 0) { std::cout << "Уравнение " << k-1 << " степени: \n";
            std::cout << P[4] << " λ^4 - (" << P[3] <<") λ^3 - (" << P[2] << ") λ^2 - (" << P[1] << ") λ - (" << P[0] <<") = 0 \n"; }
    }
//Аккуратно выведем полученные значения λ
    std::cout << "------------------------------ \n";
    std::cout << "Полученные собственные значения: \n";
    for (int i=ni; i>0; i--)
    {
        std::cout << "λ[" << ni-i+1 << "]: " << lambda[i-1] << ";\n";
    }
    std::cout << "------------------------------ \n";
    return 0;
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.06.2014, 07:31
Ответы с готовыми решениями:

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

Нахождение собственных значений и векторов матрицы методом Крылова
Уважаемые товарищи, помогите, пожалуйста. Нужно найти СВ и СЗ матрицы 5х5 методом Крылова, буду благодарен. Заранее спасибо.

Метод итераций: нахождение собственных векторов и собственных значений матрицы
Доброго времени суток. метод итерации нахождение собственных векторов и собственных значений матрицы - вот тема на которую нужно написать...

3
 Аватар для reisal78
944 / 687 / 230
Регистрация: 28.04.2013
Сообщений: 1,925
07.06.2014, 09:45
Лучший ответ Сообщение было отмечено nesteroff как решение

Решение

nesteroff,

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
import java.io.File;
/**
 * Created by Reisal78 cyberforum.ru on 07.06.2014.
 */
public class ChislMethodKrylov {
 
    static float[][] arrMult(float[][] Arr, float[][] ArrO, int m, int n, int q) //Функция перемножения матриц
    {
        float[][] MultArr;
        //Динамически создаем матрицу - результат произведения
        MultArr = new float[m][];
        for (int i = 0; i < m; i++) {
            MultArr[i] = new float[q];
        }
        ;
        //Вычисляем произведение матриц
        for (int i = 0; i < m; i++)
            for (int j = 0; j < q; j++) {
                MultArr[i][j] = 0;
                for (int k = 0; k < n; k++)
                    MultArr[i][j] += Arr[i][k] * ArrO[k][j];
            }
        return MultArr;
    }
 
    static float[][] treugArr(float[][] Arr, int n) //Приведение матрицы к треугольному виду
    {
        //Приводим матрицу A к треугольному виду
        for (int i = 0; i < n; i++) {
            //Обнуляем необходимые элементы
            for (int j = i + 1; j < n; j++) {
                float koeff = Arr[j][i] / Arr[i][i]; //Коэффициент, на который будем домножать строку
                for (int k = 0; k < n + 1; k++)
                    Arr[j][k] = Arr[j][k] - Arr[i][k] * koeff;
            }
        }
        return Arr;
    }
 
    static float[] gSolve(float[][] Arr, int n) //Нахождение переменных в матрице, приведенной к треугольному виду
    {
        float[] X;
        X = new float[n];
        //Расчет неизвестных:
        X[3] = Arr[3][4] / Arr[3][3];
        X[2] = (Arr[2][4] - Arr[2][3] * X[3]) / Arr[2][2];
        X[1] = (Arr[1][4] - Arr[1][2] * X[2] - Arr[1][3] * X[3]) / Arr[1][1];
        X[0] = (Arr[0][4] - Arr[0][1] * X[1] - Arr[0][2] * X[2] - Arr[0][3] * X[3]) / Arr[0][0];
 
        return X;
    }
 
    static float halfDiv(float[] P, float eps) //Метод половинного деления
    {
        float a = 0;
        float b = 0;
        float prec;
 
        do {
            a--;
            b++;
        } while (urTest4(a, b, P) > 0);
        System.out.println("Исходный отрезок для нахождения корней: ");
        System.out.println("[" + a + "," + b + "]\n");
        do {
            prec = b - a;
            float cent = (a + b) / 2;
            if (urTest4(a, cent, P) < 0) b = cent;
            else a = cent;
        } while (prec > eps);
 
        return a;
    }
 
    static float[] urDiv(float[] P, float a, int n) //Деление уравнения
    {
        P[n] = 0;
        for (int i = n - 1; i >= 0; i--) {
            if (i + 1 == n)
                P[i] = -P[i] + a;
            else
                P[i] = -P[i] + P[i + 1] * a;
        }
        for (int i = 0; i < n; i++)
            if (i + 1 == n)
                P[i] = -1;
            else
                P[i] = -P[i + 1];
 
        return P;
    }
 
    static float urTest4(float a, float b, float[] P) //Проверка знаков на концах отрезка
    {
        float r1 = (float) (P[4] * Math.pow(a, 4) - P[3] * Math.pow(a, 3) - P[2] * Math.pow(a, 2) - P[1] * a - P[0]);
        float r2 = (float) (P[4] * Math.pow(b, 4) - P[3] * Math.pow(b, 3) - P[2] * Math.pow(b, 2) - P[1] * b - P[0]);
 
        return r1 * r2;
    }
 
    static void dispArr(float[][] Arr, int si, int sj, String t) //Процедура отображения матрицы
    {
        System.out.println("------------------------------ \n");
        for (int i = 0; i < si; i++) {
            for (int j = 0; j < sj; j++) {
                System.out.printf(t, Arr[i][j]);
            }
            System.out.println("\n");
        }
        System.out.println("------------------------------ \n");
 
    }
 
    public static void main(String[] args) {
        File file;
        float kf, eps, a;
        float[][] A;
        float[][] B;
        float C[][];
        float[][] mC;
        float[][] c0;
        float[] P;
        float[] lambda;
        float[][] tmpArr;
        int ni, nj;
        //Открываем файл для чтения исходных данных
        file = new File("/Volumes/Macintosh HD/Users/nick_ny/Study/Chisl_method/Lab4_Krylov/Lab4_Krylov/input.txt");
        //Считываем из файла размерность массивов Ni x Nj
 
        fscanf(file, "%d", & ni);
        fscanf(file, "%d", & nj);
 
        //Создаем динамические массивы
        A = new float[ni][];
        B = new float[ni][];
        C = new float[ni][];
 
        for (int i = 0; i < ni; i++) {
            A[i] = new float[nj];
            B[i] = new float[nj];
            C[i] = new float[nj];
        }
        ;
 
        //Считываем массив B:
        for (int i = 0; i < ni; i++)
            for (int j = 0; j < nj; j++)
                fscanf(file, "%f ", & B[i][j]);
        //Считываем массив C:
        for (int i = 0; i < ni; i++)
            for (int j = 0; j < nj; j++)
                fscanf(file, "%f ", & C[i][j]);
        //Считываем число k:
        fscanf(file, "%f", & kf);
        //Считываем желаемую точность
        fscanf(file, "%f", & eps);
        fclose(file);
        //Формируем массив A, с которым будем работать (A = B + kC):
        for (int i = 0; i < ni; i++)
            for (int j = 0; j < nj; j++) {
                A[i][j] = B[i][j] + kf * C[i][j];
            }
        System.out.println("Исходная матрица A:\n");
        dispArr(A, ni, nj, "%5.2f ");
        //Блок нахождения значений C(0), C(1), C(2), C(3), C(4)
        //Создадим массив который будет хранить эти значения
        mC = new float[ni][];
        for (int i = 0; i < ni; i++)
            mC[i] = new float[ni + 1];
        //В этом массиве за C(0) примем (1, 1, 1, 1)
        for (int i = 0; i < ni; i++)
            mC[i][0] = 1;
        //Создадим массив c0, который будет хранить текущее значение C(1), C(2), C(3), C(4)
        c0 = new float[ni][];
        for (int i = 0; i < ni; i++)
            c0[i] = new float[1];
        //Перейдем к нахождению C(1), C(2), C(3), C(4)
        for (int i = 0; i < ni; i++) {
            //Заполним массив c0 текущим значением - C(i)
            for (int j = 0; j < ni; j++)
                c0[j][0] = mC[j][i];
            //Для нахождения C(i+1) умножим массив A на с0
            tmpArr = arrMult(A, c0, ni, nj, 1);
            //Занесем полученные данные в массив mC
            for (int j = 0; j < ni; j++)
                mC[j][i + 1] = tmpArr[j][0];
        }
        System.out.println("   C(0)    C(1)    C(2)    C(3)   C(4) \n");
        dispArr(mC, 4, 5, "%7.3f ");
        //Запишем систему уравнений для нахождения P1, P2, P3, P4
        treugArr(mC, 4);
        P = new float[ni + 1];
        P = gSolve(mC, 5);
        P[4] = 1;
        //Запишем получившееся уравнение с λ
        System.out.println("Характеристическое уравнение: \n");
        System.out.println(P[4] + " λ^4 - (" + P[3] + ") λ^3 - (" + P[2] + ") λ^2 - (" + P[1] + ") λ - (" + P[0] + ") = 0 \n");
        lambda = new float[ni];
        //Ищем значения λ методом половинного деления
        for (int k = 4; k > 0; k--) {
            //Будем решать полученное уравнение методом половинного деления
            a = halfDiv(P, eps);
            lambda[k - 1] = a;
            System.out.println("λ[" + (ni + 1 - k) + "]: ");
            System.out.printf("%7.3f \n", a);
            //Разделим уравнение на полученный корень, чтобы получить кубическое
            P = urDiv(P, a, k);
            //Запишем результат деления
            if (k - 1 > 0) {
                System.out.println("Уравнение " + (k - 1) + " степени: \n");
                System.out.println(P[4] + " λ^4 - (" + P[3] + ") λ^3 - (" + P[2] + ") λ^2 - (" + P[1] + ") λ - (" + P[0] + ") = 0 \n");
            }
        }
        //Аккуратно выведем полученные значения λ
        System.out.println("------------------------------ \n");
        System.out.println("Полученные собственные значения: \n");
        for (int i = ni; i > 0; i--) {
            System.out.println("λ[" + (ni - i + 1) + "]: " + lambda[i - 1] + ";\n");
        }
        System.out.println("------------------------------ \n");
    }
}

130, 131, 148, 152, 154, 156, 157 строки исправляйте сами, черт его знает в каком формате у вас данные хранятся в файле.
2
0 / 0 / 0
Регистрация: 05.03.2017
Сообщений: 8
07.10.2018, 16:53
Как вы использовали функции C в коде Java? Я что-то понять не могу( fscanf(file, "%d", &ni); fscanf(file, "%d", &nj);
0
Эксперт PythonЭксперт Java
19530 / 11067 / 2931
Регистрация: 21.10.2017
Сообщений: 23,294
07.10.2018, 17:45

Не по теме:

Conficker_, это домашнее задание

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.10.2018, 17:45
Помогаю со студенческими работами здесь

Необходимо найти множество собственных значений матрицы А методами :Крылова, Фадеева, Данилевского.
Задана матрица A (4х4): n*m 0 -m 0 n n*m n -m -m n n*m n 0...

Вычисление собственных значений и собственных векторов матрицы. Метод скалярных произведений
Курсовая работа!! Задание: &quot;Вычисление собственных значений и собственных векторов матрицы. Метод скалярных произведений&quot; ...

Нахождение собственных значений матрицы
как ее вообще писать? знаю как вычислять самостоятельно,но не на паскале..

Нахождение собственных чисел матрицы, метод Данилевского
Нужно найти собственные числа матрицы n*n.Реализовать метод данилевского. Public: int poryadok; #pragma endregion private:...

Нахождение собственных значений симметричной матрицы методом бисекции
Доброго времени суток. Подскажите пожалуйста с программой, необходимо найти собственные значения симметричной матрицы методом бисекции....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru