Компьютерный форум NoWa.cc

Компьютерный форум NoWa.cc (https://nowa.cc/index.php)
-   Visual C++ / С/C++ (https://nowa.cc/forumdisplay.php?f=302)
-   -   Симметричная матрица (https://nowa.cc/showthread.php?t=155000)

BFTFenix 01.04.2008 21:02

Симметричная матрица
 
Это матрица у которой столбец под главной диогональю равен соотведствующей строке над главно диогональю. Посути получаеться два треугольника. Так вот в моей задаче мне нужно хронить в память не всю матрицу а один из таких треугольников(я выбрал нижний). У меня возникают проблемы при вводе, вот код:
Код:

#include <iostream.h>
#include <conio.h>
int main()
{
  int m;
  cout <<"enter m:";
  cin >>m;
  int **mas=new int *[m];

  for (int i=0; i<m; i++, mas++)
      *mas=new int [i];
  mas=mas-m+1;

  cout <<"enter simmetri4nuu matricu:"<<endl;
  for (int i=0; i<m; i++)
  {
          cout <<"enter "<<(i+1)<<" stroku:"<<endl;
      for (int j=0; j<m; j++)
      {
              if (j>i)
        {
                int *t=new int;
            if (!t) {
              cout <<"Error";
              break;
            }
            cout <<"\n-";
            cin >>*t;
            delete t;
        }
        else
        {
                cout <<"\n+";
                cin >>**(mas+j);
        }
      }
          mas++;
  }
  mas=mas-m+1;

  getch();
  return 0;
}

Программа кампелируеться без проблем, но виснет приводе элемента. Какого именно зависит от ввиденого размера матрицы. Если матрица 3-3 то программа виснет при вводе 3-го элементта второй строки(он не должен хрониься в памяти).
вот ошибка:
http://www.grove.bsu.by/images/gallery/vlad@error.JPG

flipBoy 02.04.2008 03:10

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

int m;
cout <<"enter m:";
cin >>m;
int **mas=new int *[m-1];
int **tmp=mas;
for (int i=1; i<m; i++, tmp++)
*tmp=new int [i];
tmp=mas+m-2;
cout <<"enter simmetri4nuu matricu:"<<endl;
for (int i=0; i<m; i++)
{
cout <<"enter "<<(i+1)<<" stroku:"<<endl;
int k=0;
for (int j=0; j<m; j++)
{
if (j<=i)
{
int t;
cout <<"\n-";
cin >>t;
}
else
{
cout <<"\n+";
cin >>*(*tmp+k);
++k;
}
}
tmp--;
}
tmp=mas;
for (int i=0;i<m-1;++i){
for (int j=0;j<i+1;++j)
printf("%d ",tmp[i][j]);
printf("\n");
}
getch();
return 0;

Добавлено через 12 минут
for (int i=0; i<m; i++, mas++)
*mas=new int [i];
обрати внимание на этот фрагмент,тут ты создаёшь таблицу размером 0.А потом в цикле где вводишь элементы начинаешь вписывать элемент строки в таблицу размером 0.

Добавлено через 21 минуту
Замени for (int i=1; i<=m; i++, mas++)
И тут cin >>**(mas+j); замени
на *(*mas+j); чтобы правильно перемещаться по таблице, отсюда ошибка обращения к памети.

BFTFenix 02.04.2008 09:11

Ответ: Симметричная матрица
 
Цитата:

И тут cin >>**(mas+j); замени
на *(*mas+j); чтобы правильно перемещаться по таблице, отсюда ошибка обращения к памети.
Так как написано у меня я перемещаюсь в приделах одной строки, переход на нову у меня обощначаеться как mas++. А так как ты написал я буду пермемещаться по сторокам а не в приделе одной, что мне надо.

И я думаю что:

*mas=new int [0];
равносильно
*mas=new int;
веди в массиве а[1] - 2 элемента, а не 1. Или я не прав?

flipBoy 02.04.2008 12:13

Ответ: Симметричная матрица
 
Я соглашусь с тобой в первом случае, но при такой арифметике ты перемещаешься не по таблице а по таблицам. Может я не правильно тебя понял чего ты хочешь, может именно этого ты и хочешь, но тут сдвигается указатель на указатель таблицы.
cin >>**(mas+j);

BFTFenix 02.04.2008 16:51

Ответ: Симметричная матрица
 
Нет по поводу замены **(mas+j) на *(*mas+j) ты ПРАВ! Это просто я идиот. А вот по поводу выделения памяти я придерживаюсь своего мнения.

ev_Genius 02.04.2008 18:43

Ответ: Симметричная матрица
 
Цитата:

Сообщение от BFTFenix (Сообщение 1572887)
*mas=new int [0];
равносильно
*mas=new int;

Нет, не равносильно. Первый вариант вообще ошибка, т.к. ничего не выделяется, т.е. ноль элементов. Кроме того, выделенную с помощью new TYPE[n] память нужно освобождать с помощью delete[], а new TYPE - delete.

flipBoy 02.04.2008 19:27

Ответ: Симметричная матрица
 
По поводу выделения памяти, я проверял в несколких источниках, в том числе www.cplusplus.com. Там написано как раз что :
int *point=new int[n], где n - это количество элементов под которые выделяется память. :quest:

BFTFenix 02.04.2008 19:32

Ответ: Симметричная матрица
 
Ну программа покрайней мере работает правельно.
сегодня чуть по позже проверю точно этот нюанс.

zss 02.04.2008 21:47

Ответ: Симметричная матрица
 
Предлагаю альтернативное решение:
Создать класс треугольных матриц.
Код:

class matr3
{
private:
  int m; // длина строки
  double *p; // указатель на массив
public:
  matr3(int m0):m(m0){p=new double [m*(m+1)/2];} // конструктор выделяет память только под треугольную часть
  ~matr3(){delete[] p;} // деструктор удаляет выделенную память
  double get(int i,int j); // получить элемент массива
  void set(double x, int i, int j);  // задать элемент массива
};

При желании можно даже перегрузить операцию []

BFTFenix 03.04.2008 19:31

Ответ: Симметричная матрица
 
2 zss:
хороший подход, мне как раз нужно несколько таких матриц.
2 flipBoy:
вот код:
Код:

#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
int main()
{
        int *p=new int[0];
        int *d=new int[1];
        cout <<"*p=";
        cin >>*p;
        cout <<"*d=";
        cin >>*d;
        cout <<"*(d+1)=";
        d++;
        cin >>*d;
        cout <<"выводим все в порядке ввода:";
        cout <<*p<<'\t'<<*(d-1)<<'\t'<<*d;
        getch();
        return 0;
}

Выводит именно то что я и ввожу, так что думайте сами.....

zss 04.04.2008 11:43

Ответ: Симметричная матрица
 
Цитата:

Сообщение от BFTFenix (Сообщение 1576678)
2 zss:
хороший подход, мне как раз нужно несколько таких матриц.

Когда есть класс, то представителей этого класса можете
создавать сколько угодно:
matr3 m1,m2,m3[1000];

BFTFenix 04.04.2008 17:52

Ответ: Симметричная матрица
 
Цитата:

Сообщение от zss (Сообщение 1578003)
Когда есть класс, то представителей этого класса можете
создавать сколько угодно:
matr3 m1,m2,m3[1000];

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

flipBoy 08.04.2008 19:37

Ответ: Симметричная матрица
 
Цитата:

И я думаю что:
*mas=new int [0];
равносильно
*mas=new int;
веди в массиве а[1] - 2 элемента, а не 1. Или я не прав?
Если дашь индекс 0, то будет таблица с одним элементом, так как ты сказал,и даже если 1, то тоже будет один элемент.Программа работает правильно, потому что при компиляции программы и последующем запуске для порграммы выделяется больше памяти, чем требуется непосредственно для задекларированных перемменных, поэтому нету ошибки обращения к памяти при пересечении границы таблицы. И операции производятся над ячейками памяти не пренадлежащими таблице. Операционная система не может следить за каждым байтом памяти, она следит за блоком. Это черевато последующим затиранием данных не хранящихся в памяти. Или может я не прав. Я пришёл к
такому выводу, так что безопаснее безусловно делать так как я писал выше, и резервировать памяти столько сколько нужно.

seimur 21.04.2008 18:37

Ответ: Симметричная матрица
 
Код:

#include <iostream>

using namespace std;

void main()
{
        int rows = 0;

        cout << "Rows in matrix(positive integer): ";
        cin >> rows;

        int** matrix = new int*[rows];
        for (int row = 0; row < rows; ++row)
        {
                matrix[row] = new int[row+1];
                cout << "Row[" << row << "]= ";
                for(int col = 0; col <= row; ++col)
                        cin >> matrix[row][col];
        }

        // Do something here..

        // Free memory..
        for (int row = 0; row < rows; ++row)
                delete[] matrix[row];

        delete[] matrix;
}



Текущее время: 13:16. Часовой пояс GMT +3.

Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2026, vBulletin Solutions, Inc. Перевод: zCarot
Copyright ©2004 - 2026 NoWa.cc

Время генерации страницы 0.03639 секунды с 9 запросами