Jak za pomocą pętli utworzyć taką macierz?

0

Witam:) Mam dziwne zadanie, z którym nie potrafię sobie poradzić. W sumie to 3 zadania, ale na razie wziąłem się za 1 z nich. Mianowiecie: jak za pomocą 2 pętli utworzyć taką macierz: http://pastie.org/private/fniabuvpunfz8sihz8q ? (a i b podaje użytkownik, rozmiar może być dowolny)

To macierz z pastie, wkleiłem tam, bo tu się trochę rozjechało:

   |	1	2	3	4
-------------------------------------
  |
1 |	-a	a	0	0
  |
2 |	b	-(a+b)	a	0	
  |
3 |	0	b	-(a+b)	b
  |
4 |	0	0	b	-b
  |
  |

Mi nic do głowy nie przychodzi, napisałem jedynie sam wstęp :((

#include <iostream>
using namespace std;

float **macierz1(float a, float b, int N)
{
    float **macierz = new float*[N];
    for(int i=0; i<N; i++)
        macierz[i] = new float[N];

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

        }
    }
}

int main()
{
    float a, b;
    int N;

    cout << "Podaj a\n";
    cin >> a;
    cout << "Podaj b\n";
    cin >> b;
    cout << "Podaj N (rozmiar macierzy)\n";
    cin >> N;

    float *ma1 = macierz(a, b, N);

    for(int i=0; i<N; i++)
        for(int j=0; j<N: j++)
            cout << "macierz[" << i << "][" << j << "] = " << ma1[i][j] << "\n";

    return 0;
}

0

Poradziłem sobie z 1 i ost wierszem, ale te "srodkowe" - z nimi mam problem :(

#include <iostream>
using namespace std;

float **macierz1(float a, float b, int N)
{
    float **macierz = new float*[N];
    for(int i=0; i<N; i++)
        macierz[i] = new float[N];

    for(int i=0; i<N; i++)
        for(int j=0; j<N; j++)
            macierz[i][j] = 0;

    for(int i=0; i<N; i++)
    {
        for(int j=0; j<N; j++)
        {
            if(i == 0 && j == 0)
                macierz[i][j] = a;
            if(i == 0 && j == 1)
                macierz[i][j] = -a;
            if(i == N-1 && j == N-1)
                macierz[i][j] = -b;
            if(i == N-1 && j == N-2)
                macierz[i][j] = b;
        }
    }

    return macierz;
}

int main()
{
    float a, b;
    int N;

    cout << "Podaj a\n";
    cin >> a;
    cout << "Podaj b\n";
    cin >> b;
    cout << "Podaj N (rozmiar macierzy)\n";
    cin >> N;

    float **ma1 = macierz1(a, b, N);

    for(int i=0; i<N; i++)
        for(int j=0; j<N; j++)
            cout << "macierz[" << i << "][" << j << "] = " << ma1[i][j] << "\n";

    return 0;
}
1

Ja bym doradził zainteresowanie się klasą std::vector, no ale jeżeli już ma być na zwykłych tablicach:

#include <iostream>
using namespace std;

double** create_matrix(size_t size)
{
    double** result = new double*[size];
    for(size_t i = 0; i < size; ++i)
        result[i] = new double[size]();

    return result;
}

void destroy_matrix(double** matrix, size_t size)
{
    while(size--)
        delete[] matrix[size];
    delete[] matrix;
}

void fill_matrix(double** matrix, size_t size, double a, double b)
{
    for(size_t i = 1; i < size; ++i)
    {
        matrix[i][i - 1] = b;
        matrix[i - 1][i] = a;
        matrix[i][i] = -(a + b);
    }
    matrix[0][0] = -a;
    matrix[size - 1][size - 1] = -b;
}

int main()
{
    const double a = 4;
    const double b = 2;
    const size_t size = 5;

    double** matrix = create_matrix(size);
    fill_matrix(matrix, size, a, b);

    for(size_t i = 0; i < size; ++i)
    {
        for(size_t j = 0; j < size; ++j)
            cout << matrix[i][j] << ' ';
        cout << '\n';
    }

    destroy_matrix(matrix, size);

    return 0;
}
0

@Karolaq: dzięki za odpowiedź! :) Juz działa. Drugie moje zadanie o utworzenie takiej macierzy:

  |	0	1	2	3	4
---------------------------------------------------
0 |	-a	a	0	0	0
  |
1 |	b    -(a+b)	a	0	0
  |
2 |	0      2*b  -(a+2*b)	0	0
  |
3 |	0	0	3*b  -(a+3*b)	0
  |
4 |	0	0	0	3*b	-3*b
  |
  |

Pozwoliłem sobie wykorzystać Twój kod do napisania tego, chyba jest ok? :

#include <iostream>
#include <iomanip>
using namespace std;

double** create_matrix(size_t size)
{
    double** result = new double*[size];
    for(size_t i = 0; i < size; ++i)
        result[i] = new double[size]();

    return result;
}

void destroy_matrix(double** matrix, size_t size)
{
    while(size--)
        delete[] matrix[size];
    delete[] matrix;
}

void fill_matrix(double** matrix, size_t size, double a, double b)
{
    for(size_t i = 1; i < size; ++i)
    {
        matrix[i][i - 1] = b;
        matrix[i - 1][i] = a;
        matrix[i][i] = -(a + b);

        if(i == 1)
        {
            matrix[i][i - 1] = b;
            matrix[i - 1][i] = a;
            matrix[i][i] = -(a + b);
        }

        if(i == 2)
        {
            matrix[i][i - 1] = 2*b;
            matrix[i - 1][i] = a;
            matrix[i][i] = -(a + 2*b);
        }

        if(i >= 3)
        {
            matrix[i][i - 1] = 3*b;
            matrix[i - 1][i] = a;
            matrix[i][i] = -(a + 3*b);
        }

    }
    matrix[0][0] = -a;
    matrix[size - 1][size - 1] = -3*b;
}

int main()
{
    const double a = 4;
    const double b = 2;
    const size_t size = 10;

    double** matrix = create_matrix(size);
    fill_matrix(matrix, size, a, b);

    for(size_t i = 0; i < size; ++i)
    {
        for(size_t j = 0; j < size; ++j)
            cout << setw(3) << matrix[i][j] << ' ';
        cout << '\n';
    }

    destroy_matrix(matrix, size);

    return 0;
}
1

Jakoś nie dostrzegam żadnej prawidłowości w tym przykładzie. Zakładając, że ten kod jest prawidłowy, to pomyśl nad tym, jak go uprościć. Zauważ, że dużo podobnego kodu się powtarza, a różnica jest tylko przy współczynniku b. Może najpierw wylicz jego wartość, a potem wykonaj przypisania.

0

Tzn chyba nie ma być tu nic logicznego ... nie wiem;) Dostałem taką pracę domową jako ćwiczenie pętli:) Ok, popróbuję z Twoimi radami, może mi się uda, w razie czego napiszę tutaj jeszcze:)

0

Hej, niestety nie udało mi się tego uprościć, więc chyba zostawię to, tak, jak jest. Mam jednak nieco trudniejsze zadanie z ktorym nie potrafię sobie poradzić. Chodzi o zbudowanie takiej macierzy (suma liczb w każdej z piziomych linii musi być równa zero (suma wiersszzy)). Mógłby ktoś poratować?

  |        0        1        2        3        4	
-------------------------------------------------------
0 |        -a     a/4       a/4       a/4      a/4	
  |
1 |        b  -(a+b)        a/4      2a/4     3a/4	
  |
2 |        0        b  	  -(a+b)     a/2       a/2	
  |
3 |        0        0        b      -(a+b)     a	
  |
4 |        0        0        0        b        b	
  |
  |
 

oczywiście w 1 wierszu może być inna podziałka, np. 3 wtedy dla 1 wiersza by było:

-a   a/3   a/3    a/3  0

No i wtedy pozostałe wiersze też muszą się zmienić

0

moja rada: użyj mózgu

0

Możesz nie obrażać? To są moje początki i mam problemy - co w tym dziwnego, Ty od razu wszystko wiedziałeś? Widocznie już od wczoraj próbowałem i nie wymyśliłem nic, dlatego chciałem zapytać o pomoc ...

0

Cos zaczalem ale i tak mi nie idzie;/ Moge Cie @Karolaq ponownie poprosić o pomoc?

Chce taką macierz:

 
  |        0        1        2        3        4        
-------------------------------------------------------------------------------------
0 |       -a     a/4       a/4       a/4      a/4        
   |
1 |       b  -(3/4a+b)   a/4      a/4     a/4        
   |
2 |        0      b  -(2/4a+b)     a/4       a/4        
   |
3 |        0        0        b   -(a/4+b)     a/4        
   |
4 |        0        0        0        b        -b        
   |

To moj kod, caly czas bazuje na Twoim,ale tylko 1 wiersz wypelnilem:(:

#include <iostream>
#include <iomanip>
using namespace std;

double** create_matrix(size_t size)
{
    double** result = new double*[size];
    for(size_t i = 0; i < size; ++i)
        result[i] = new double[size]();

    return result;
}

void destroy_matrix(double** matrix, size_t size)
{
    while(size--)
        delete[] matrix[size];
    delete[] matrix;
}

void fill_matrix(double** matrix, size_t size, double a, double b)
{
    int ile = 0;

    //pierwszy wiersz
    for(int i=0; i<size; i++)
    {
        if(ile < b)
        {
          matrix[0][i+1] = a/b;
          ile ++;
        }
    }

    //reszta
    for(size_t i = 1; i < size; ++i)
    {
        matrix[i][i - 1] = b;
    }

    matrix[0][0] = -a;
    matrix[size - 1][size - 1] = -b;
}

int main()
{
    const double a = 4;
    const double b = 2;
    const size_t size = 5;

    double** matrix = create_matrix(size);
    fill_matrix(matrix, size, a, b);

    for(size_t i = 0; i < size; ++i)
    {
        for(size_t j = 0; j < size; ++j)
            cout << setw(3) << matrix[i][j] << ' ';
        cout << '\n';
    }

    destroy_matrix(matrix, size);

    return 0;
}
0

No moze tu troche lepiej ale niewiele chyba, bo sie wywala :( :

#include <iostream>
#include <iomanip>
using namespace std;

double** create_matrix(size_t size)
{
    double** result = new double*[size];
    for(size_t i = 0; i < size; ++i)
        result[i] = new double[size]();

    return result;
}

void destroy_matrix(double** matrix, size_t size)
{
    while(size--)
        delete[] matrix[size];
    delete[] matrix;
}

void fill_matrix(double** matrix, size_t size, double a, double b)
{
    int ile = 0;

    //pierwszy wiersz
    for(int i=0; i<size; i++)
    {
        if(ile < b)
        {
          matrix[0][i+1] = a/b;
          ile ++;
        }
    }

    ile = 0;

    //reszta
    for(size_t i = 1; i < size; ++i)
    {
        matrix[i][i - 1] = b;
        if(ile < b)
        {
            matrix[i][i+1] = a/b;
            ile ++;
        }
        matrix[i][i] = -(a/ile + b);
        ile = 0;
    }

    matrix[0][0] = -a;
    matrix[size - 1][size - 1] = -b;
}

int main()
{
    const double a = 2;
    const double b = 8;
    const size_t size = 8;

    double** matrix = create_matrix(size);
    fill_matrix(matrix, size, a, b);

    for(size_t i = 0; i < size; ++i)
    {
        for(size_t j = 0; j < size; ++j)
            cout << setw(3) << matrix[i][j] << ' ';
        cout << '\n';
    }

    destroy_matrix(matrix, size);

    return 0;
}
0

Wzoru jako-takiego nie posiadam :( Miałem podane tylko kilka przykładów macierzy, druga z tego samego przykładu wygląda tak:

[code] | 0 1 2 3 4 5 6 7 8 9 10

0 | -a a/8 a/8 a/8 a/8 a/8 a/8 a/8 a/8 0 0
|
1 | b -(a+b) a/8 a/8 a/8 a/8 a/8 a/8 a/8 a/8 0
|
2 | 0 b -(a+b) a/8 a/8 a/8 a/8 a/8 a/8 a/8 a/8
|
3 | 0 0 b -(7a/8+b) a/8 a/8 a/8 a/8 a/8 a/8 a/8
|
4 | 0 0 0 b -(6
a/8+b) a/8 a/8 a/8 a/8 a/8 a/8
|[/code]

Tą 8 (czyli przez ile podzielić) ma podać użytkwonik .., czyli zamiast 8 powinno być jakieś "p"

0

Juz nieco lepiej, ale mam problem ze srodkowymi wierszami:

#include <iostream>
#include <iomanip>
using namespace std;

double** create_matrix(size_t size)
{
    double** result = new double*[size];
    for(size_t i = 0; i < size; ++i)
        result[i] = new double[size]();

    return result;
}

void destroy_matrix(double** matrix, size_t size)
{
    while(size--)
        delete[] matrix[size];
    delete[] matrix;
}

void fill_matrix(double** matrix, size_t size, double a, double b, int p)
{
    int ile = 0;

    //pierwszy wiersz
    for(int i=0; i<size; i++)
    {
        if(ile < p)
        {
          matrix[0][i+1] = a/p;
          ile ++;
        }
    }

    ile = 0;

    //reszta
    for(size_t i = 1; i < size; ++i)
    {
        matrix[i][i - 1] = b;
        for(size_t j=1; j<size; ++j)
        {
            if(ile < p)
            {
                matrix[j][j+1] = a/p;
                ile ++;
            }
        }
        matrix[i][i] = -(ile*a/p + b);
        ile = 0;
    }

    matrix[0][0] = -a;
    matrix[size - 1][size - 1] = -b;
}

int main()
{
    const double a = 2;
    const double b = 8;
    const double p = 8;
    const size_t size = 11;

    double** matrix = create_matrix(size);
    fill_matrix(matrix, size, a, b, p);

    for(size_t i = 0; i < size; ++i)
    {
        for(size_t j = 0; j < size; ++j)
            cout << setw(4) << matrix[i][j] << ' ';
        cout << '\n';
    }

    destroy_matrix(matrix, size);

    return 0;
}
0

A może użyć tablicę dwuwymiarową matrix[5][n]?
Dwie pętle, zmienna dodatkowa c zlicza krotnosc kolumn i jest znacznikiem, czy suma w wierszu jest już 0 , czy jeszcze jest nadmiar.

 
for( i=0; i<5; i++ ) 
  for( j=0; j<n; j++ ) {
    matrix[i][j] = 0; 
    int c = min(n-i-1, p); // krotność kolumn do końca wiersza lub p  
    if( 1==i-j ) matrix[i][j] += b; // pozycje pod przekątna główną
    if( 0==i-j ) matrix[i][j] = -b - c*a/p; // przekątna
    if( 0<j-i && c ) { matrix[i][j] += a/p; c--; } // macierz trójkątna górna
}
0

A czy to aby na pewno zadziała dla macierzy NxN? Zaraz sprawdze, dzieki!

0

Niestety źle :(

Twoja metoda daje mi takie coś: (dla a=1,b=1,p=2,size=5)

 
 -1  0.5  0.5  0.5  0.5
   1   -2  0.5  0.5  0.5
   0    1   -2  0.5  0.5
   0    0    1 -1.5  0.5
   0    0    0    1   -1

a powinno być

  -1  0.5  0.5  0  0
   1   -2  0.5  0.5  0
   0    1   -2  0.5  0.5
   0    0    1 -1.5  0.5
   0    0    0    1   -1
0

Naprawde nikt nie jest w stanie mi pomoc?:( ja nic nie moge wymyslic, ciagle cos źle mi wychodzi ...

0

prowadzisz monolog ?

0

Nie, czekam, być może ktoś mi odpowie.

2

Jeżeli dobrze zrozumiałem macierz, to powinno to wyglądać tak:

#include <iostream>
#include <cmath>
#include <iomanip>
#include <cassert>

using namespace std;

double** create_matrix(size_t size)
{
    double** result = new double*[size];
    for(size_t i = 0; i < size; ++i)
        result[i] = new double[size]();

    return result;
}

void destroy_matrix(double** matrix, size_t size)
{
    while(size--)
        delete[] matrix[size];
    delete[] matrix;
}

void fill_matrix(double** matrix, size_t size, double a, double b, size_t p)
{
    for(size_t row = 0; row < size; ++row)
    {
        const size_t last = min(row + 1 + p, size);
        const size_t count = last - row - 1;
        for(size_t col = row + 1; col < last; ++col)
        {
            matrix[row][col] = a / p;
        }

        matrix[row][row] = -a * count / p;
        if(row > 0)
        {
            matrix[row][row] -= b;
            matrix[row][row - 1] = b;
        }
    }

}

bool validate(double** matrix, size_t size, double eps = 0.000001)
{
    for(size_t i = 0; i < size; ++i)
    {
        double sum = 0;
        for(size_t j = 0; j < size; ++j)
            sum += matrix[i][j];
        if(abs(sum) > eps) return false;
    }

    return true;
}

int main()
{
    const double a = 2;
    const double b = 8;
    const size_t p = 8;
    const size_t size = 11;

    double** matrix = create_matrix(size);
    fill_matrix(matrix, size, a, b, p);

    for(size_t i = 0; i < size; ++i)
    {
        for(size_t j = 0; j < size; ++j)
            cout << setw(4) << matrix[i][j] << ' ';
        cout << '\n';
    }

    assert(validate(matrix, size));
    destroy_matrix(matrix, size);

    return 0;
}
0

Wygląda na to, że jest ok:) Ślicznie dziękuję,bardzo mi pomogłeś:) Próbowałem sobie to rozpisać krok po kroku ale coś mi nie szło jakoś... Dziękuję:) To chyba było już ostatnie zadanie:)

Nie pomyślałbym, że można tak skomplikować tworzenie tablicy 2 wymiarowej i wypełnianie jej. (Chodzi mi o treść zadania)

DZIĘKUJĘ.

1 użytkowników online, w tym zalogowanych: 0, gości: 1