Задание такое: заполнить матрицу Nного порядка и посчитать
1) Сумму элементов в тех строках, которые не содержат отрицательных элементов
2) минимум среди сумм элементов диагонале, параллельных главной диагонали матрицы. Если первое работает на ура, то со вторым возникли такие затруднения:
При подсчёте сумм диагоналей параллельных главной, в цикле где это происходит есть вылет за массив у переменных x и y хотя в while чётко прописано, что если ((x < N - 1) ИЛИ (y < N - 1)) то считать сумму диагонали, однако это условие игнорируется и x выходит дальше за массив. Наблюдается в g++ и visual-c Вопрос, почему игнорируются условия в while?
// PR5_din_arrays.cpp: определяет точку входа для консольного приложения.
//
/*Дана целочисленная квадратная матрица. Определить:
1) Сумму элементов в тех строках, которые не содержат отрицательных элементов
2) минимум среди сумм элементов диагонале, параллельных главной диагонали матрицы.
*/
// PR5_din_arrays.cpp: определяет точку входа для консольного приложения.
//
/*Дана целочисленная квадратная матрица. Определить:
1) Сумму элементов в тех строках, которые не содержат отрицательных элементов
2) минимум среди сумм элементов диагонале, параллельных главной диагонали матрицы.
*/
#include "stdafx.h"
#include <time.h>
#include <iomanip>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int N = 2;
cout << "input the size of matrix" << endl;
cin >> N;
while (N < 2)
{
cout << "incorrect value!" << endl;
cout << "input the size of matrix" << endl;
cin >> N;
}
/* в куске выше я объявляю N которая отвечает за порядок матрицы. После её ввода идёт защита от дурака, которая не пускает дальше, если введённое значение меньше 2.
В случае если будет матрица первого порядка, то задача потеряет смысл*/
int **matrix = new int*[N];
for (int count = 0; count < N; count++)
{
matrix[count] = new int[N];
}
/*выше объявляю саму матрицу*/
int *sum = new int[N]; // в этот массив пишутся суммы строк. Должен быть динамическим ибо мы не знаем какого порядка будет матрица
int ds = (N - 1) * 2; // это формула вычисления количества диагоналей параллельных главной. Чтобы включить сюда главную диагональ, нужно к полученному результату прибавить единицу
int *diasum = new int[ds+1]; // массив в который будут попадать суммы диагоналей
srand(time(NULL));
cout << "Original array:" << endl;
for (int i = 0; i < N; i++)
{
sum[i] = 0; // обнуление массива сумм! ОБЯЗАТЕЛЬНО! иначе на выходе получим очень интересные и многозначные данные которые называются мусором
for (int j = 0; j < N; j++)
{
matrix[i][j] = rand() % 101 - 50;
cout << setw(6) << left << matrix[i][j]; // тут setw(6) устанавливает расстояние между символами потока вывода, left сдвигает всё влево. ЧТОБЫ РАБОТАЛО НУЖЕН <iomanip>
}
cout << endl;
}
cout << "sdelan vyvod - perehod k vychisleniyu summy stroki" << endl;
/*в куске выше я рандомил матрицу от -50 до 50(100 чисел и сдвиг по числовой линии влево на 50 101 потому что 0 тоже число*/
//вычисления
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (matrix[i][j] < 0)
{
sum[i] = 0;
break;
}
else
{
sum[i] = sum[i] + matrix[i][j];
}
}
}cout << "vycheslena stroka - perehod k onuleniyu DIASUM" << endl;/*выше я иду по строке и проверяю число на отрицательность. Если отрицательное - обнуляю сумму и выхожу из цикла, таким образом перехожу на след. строку
Если же всё окей, то просто прибавляю число в sum[i]. */
/*
_____________________________________________________________________
Ниже пойдёт отработка диагоналей
_____________________________________________________________________
*/
for (int i = 0; i < ds; i++)
{
diasum[i] = 0;
cout << diasum[i] << " ";
}
cout << endl;
cout << "DIASUM obnulena - perehod k vychisleniyu summy diagonali - 1 prohod" << endl;
int x = 0;
int y = 0;
int iter = 0; // Сюда ловим место на котором мы остановилис в цикле ниже, чтобы с него затем продолжить.
for (int i = 1; i < N; i++)
{
x = i;
y = 0;
cout << x << " " << y << " " << matrix[y][x] << endl;
while ((x < N - 1) || (y < N - 1))
{
diasum[i - 1] = diasum[i - 1] + matrix[y][x]; // p.s вот здесь и происходят интересные вещи. при N = 4 x не должен быть больше 3, но он таки почему-то больше, хотя в цикле while написано о том, что если x или y больше 3 то вывалиться и посчитать следующую диагональ(или идти дальше если цикл for закончился
x++;
y++;
iter = i - 1;
}
}
for (int i = 0; i <= iter; i++) //вывод сумм чисел, пока что в лобешник все подряд.
{
cout << " " << diasum[i];
}
cout << endl;
cout << "DIASUM obnulena - perehod k vychisleniyu summy diagonali - 2 prohod" << endl;
for (int i = 1; i < N; i++)
{
y = i;
x = 0;
cout << x << " " << y << " " << matrix[y][x] << endl;
while ((y < N - 1) || (x < N - 1))
{
diasum[iter + i] = diasum[iter + i] + matrix[y][x]; // а здесь после нескольких шагов можно поймать ACCESS_VIOLATION
x++;
y++;
}
}
// конец блока отработки диагоналей.
for (int i = 0; i < ds; i++) //вывод сумм чисел, пока что в лобешник все подряд.
{
cout << " " << diasum[i];
}
cout << endl;
cout << "perehod k vyvodu" << endl;
for (int i = 0; i < N; i++) //вывод сумм чисел, пока что в лобешник все подряд.
{
cout <<" " <<sum[i];
}
cout << endl;
//cout << ds;
system("pause"); // задерживаем консоль до ввода клавиши
return 0;
}
Примечания 1. я знаю о том, что в коде может быть немного странная работа с дин.массивом diasum 2. код комментировался до написания куска отработки диагоналей и был прокомментирован для одногруппников.
Должно быть while ((x < N - 1) && (y < N - 1)). Так как Вы проверяете И тот (x) И тот (y) диапазон, а не хотя бы один.
Рассмотрим Ваш цикл while:
x = i;
y = 0;
while ((x < N - 1) || (y < N - 1)) {
//...
x++;
y++;
}
Перед циклом x
у нас всегда больше нуля.
y
же всегда будет равно нулю.
Условие цикла гласит
продолжать пока
x меньше N - 1
ИЛИ
y меньше N - 1
На каждой итерации x и y увеличиваются на 1. Всё это значит, что при i == 2 мы уже получим выход за пределы массива. Предлагаю для простоты рассмотреть примерчик. Пусть N == 3, i == 1.Тогда x == 1, y == 0.Получаем условие: (1 < 2) || (0 < 2) оно дает true, поэтому продолжаем цикл.В цикле x и y увеличиваются.Дальше по итерациям: (2 < 2) || (1 < 2) == true (3 < 2) || (2 < 2) == false Вышли из while и начинается новая итерация for: x == 2, y == 0 (2 < 2) || (0 < 2) == true (3 < 2) || (1 < 2) == true Как видим, x уже равен трем, а условие дает true, поэтому мы успешно заходим в цикл и выходим за пределы выделенной памяти.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Собственно не могу понять в чем же разница между 2мя этими функциями, когда они дают идентичные результаты