# Native Code > برنامه نویسی با C > برنامه نویسی با زبان C و ++C >  ماتریس

## nokhodi

چطوری میتونم داخل یک ماتریس N*N ( که N عددی فرد باشه) یک لوزی بکشیم مثل عکس نمونه یی که گذاشتم...
خونه هایی که باید M داخلشون نوشته بشه هیچ ربطی از نظر عددی بهم ندارن :( گیج شدم



سپاس

----------


## nokhodi

به غیر رابطه عددی که اثرا توی برنامه های ماتریس استفاده میشه( و من هنوز توی این مثال نتونستم بفهممش)

آیا امکان داره به عنوان مثال این ماتریس به 4 ماتریس کوچکتر تبدیل بشه که قطر های اصلی و فرعیشون باید با M پر بشه؟!

----------


## ali chegini

سلام.شاید این ایده خوبی باشه.
8udw4c34.jpg

----------


## aminsaeedi

به نظرم این جواب نمیده چون وقتی ما خط چهارم رو چاپ کنیم دیگه به خط های قبلی دسترسی نداریم

شاید اگر در اول کار تعداد ستون +1 رو M بذاریم و یکی اضافه و یکی کم کنیم تا به صفر و حداکثر برسیم و سپس برعکس تا سطر آخر، شاید به نتیجه برسیم

----------


## Ananas

bool IsInLine(const int i, const int j, const int width)
{
    int center = (width / 2);
    return ((i + j == center) ||
            (i - j == center) ||
            (j - i == center) ||
            (j + i == center * 3));
};

----------


## Ananas

و یا :

bool IsInLine(const int i, const int j, const int width)
{
    int c = (width / 2);
    return ((abs(j + i - 2 * c) == c) ||
            (abs(i - j)         == c));
};

----------


## aminsaeedi

دوست عزیز نمی خواهید این هارو توضیح بدهید

----------


## Ananas

واضح نیست؟
 i, j  که اندیسه افقی و عمودی هست و width هم تعداد سطر یا ستون رو مشخص میکنه. تو یک حلقه ی تکرار، کل عناصر آرایه رو طی میکنید و برای هر عضو، این تابع رو اجرا میکنید. اگر تابع true برگردونه اون عضو روی محیط لوزی هست و اگر false برگردونه اون عضو روی محیط لوزی نیست.

----------


## aminsaeedi

مرکز در ردیف اول از تقسیم تعداد ستون بر ۲ و در کل +۱ بدست میاد نه فقط تقسیم بر ۲خالی

----------


## Ananas

اندیس ها در C++‎‎‎‎ برای آرایه از 0 شروع میشه نه 1. بخاطر همین نیازی نیست با 1 جمع کنیم بعد منهای یک کنیم.
در ضمن توابعی که نوشتم امتحان شدن. درست کار میکنه.
مثلا اگر 7 ستون داشته باشیم تقسیم به 2 کنیم حاصل میشه 3، که در واقع اندیس 3، عضو چهارم از آرایه رو مشخص میکنه.

----------


## ali chegini

اگه بخوای کل آرایه رو پیمایش کنی تو حالت n*n جواب نمی گیری . اگر n عدد  برگی باشه حلقه for تو در تو مجبوره n به توان 2 بار اجرا شه .
#include <iostream>
#include <cmath>
#include <vector>

using namespace std;

int width;
int height;
int i;
int j;

int main()
{

    cout << "enter matrix i , j , width : " << endl;
    int i,j,w;
    cin >> i >>  j >> w;
    cout <<endl;
    width=w;
    height=i;

    //i*j matrix;
    vector< vector<int> > matrix(i,std::vector<int>(j));

    int midx=width/2;
    int midy=height/2;
    //(0,0)=(0,midy);
    //y=x and m=-1;

    int x1=0;
    int y1=midy;
    for(int k=0;k<=midx;k++)
    {
        matrix[y1][x1]=1;
        x1++;
        y1++;
    }

    x1=0;
    y1=midy;
    for(int k=0;k<=midx;k++)
    {
        matrix[y1][x1]=1;
        x1++;
        y1--;
    }

    x1=midx;
    y1=0;
    for(int k=0;k<=midx;k++)
    {
        matrix[y1][x1]=1;
        x1++;
        y1++;
    }

    x1=midx;
    y1=height-1;
    for(int k=0;k<=midx;k++)
    {
        matrix[y1][x1]=1;
        x1++;
        y1--;
    }


    for(int k=0;k<i;k++)
    {
        for(int m=0;m<j;m++)
        {
            cout << matrix[k][m];
        }
        cout <<"\n";
    }

    return 0;
}

----------


## ali chegini

به جز حلقه آخر که برای نمایش ماترس هست و میتونی حذفش کنی.
4 تا حلقه داریم که n/2 بار اجرا میشه و میشه 4 ضربدر n/2 که میشه 2n

----------


## nokhodi

> اگه بخوای کل آرایه رو پیمایش کنی تو حالت n*n جواب نمی گیری . اگر n عدد  برگی باشه حلقه for تو در تو مجبوره n به توان 2 بار اجرا شه .
> #include <iostream>
> #include <cmath>
> #include <vector>
> 
> using namespace std;
> 
> int width;
> int height;
> ...


دو تا تابعی که دوستمون نوشت رو متوجه شدم ...البته هنوز وقت نکردم برنامه کاملش رو با استفاده از اون تابع بنویسم...

برنامه شما رو و اون خط اولی که گفتید رو که N*N نمیشه رو اینا رو متوجه نشدم...میشه لطفا بیشتر توضیح بدین...


بعدا نوشت :
اینو هم یادم رفت بگم
*N*N جزو شرایط سوال هست و همچنین فرد بودن N ها... رعایت شدنشون الزامیه...*

----------


## Ananas

> گر n عدد  برگی باشه حلقه for تو در تو مجبوره n به توان 2 بار اجرا شه


بالاخره قسمت های خالی هم باید با مقدار لازم پر بشن. پس طی شدن حلقه لازمه. اما اگه نخوای تابع زیاد اجرا شه میتونیم یک بار کل ماتریس رو مثلا با صفر پر کنیم بعد با فرمول زیر قسمتهایی که لازم هست رو با کاراکتر مثلا "M" مقدار بدیم. ت. یک حلقه ی ساده به تعداد n:

void SetMatrixMap(char * pMatrix, int N)
{
    int j = N / 2;
    for (int i = 0; i < N; i++)
    {
        pMatrix[abs(j) * N + i] = 'M';
        pMatrix[(N - abs(j) - 1) * N + i] = 'M';
        j--;
    };
};

----------


## ali chegini

نقل قول (  برنامه شما رو و اون خط اولی که گفتید رو که N*N نمیشه رو اینا رو متوجه نشدم...میشه لطفا بیشتر توضیح بدین... )
 بهش میگن پیچیدگی زمانی . اینا رو ببین :
http://fa.wikipedia.org/wiki/%D8%B2%...8C%D8%AA%D9%85
http://fa.wikipedia.org/wiki/%D9%BE%...A7%D9%86%DB%8C

تو کتاب طراحی الگوریتم یا ساختمان داده مطالبی دربارش گفته میشه.

روش آخر *Ananas* هم جالبه . ممنون *Ananas*

----------


## nokhodi

در مورد هدر vector هم میشه یه توضیح بدین?
برنامه شما بدون مشکل اجرا شد...

ویرایش :
بر نامه رو روی کاغذ تریس کردم متوجه شدم...فقط همون سوال وکتور پا برجاست:(


ananas عزیز
برنامه رو دارم با قطعه برنامه های شما هم مینویسم اما هرطوری مینویسم به مشکل بر میخورم:(

----------


## Ananas

#include "iostream"

using namespace std;


int GetIndex(const int i, const int j, const int N)
{
    return (j * N + i);
};

void SetMatrixMap(char * pMatrix, int N)
{
    int j = N / 2;
    for (int i = 0; i < N; i++)
    {
        pMatrix[GetIndex(i,     abs(j),     N)] = 'M';
        pMatrix[GetIndex(i, N - abs(j) - 1, N)] = 'M';
        j--;
    };
};

int main()
{
    while (true)
    {
        int N;
        cout << "N = ";
        cin >> N;
        char * pMatrix = (char *)malloc(sizeof(char) * N * N);
        for (int i = 0; i < N * N; i++)
        {
            pMatrix[i] = '|';
        };
        SetMatrixMap(pMatrix, N);
        for (int j = 0; j < N; j++)
        {
            for (int i = 0; i < N; i++)
            {
                cout << pMatrix[GetIndex(i, j, N)] << " ";
            };
            cout << endl;
        };
        free(pMatrix);
        cout << "--------------------------------" << endl;
    };
    return 0;
}

----------


## nokhodi

Ananas  عزیز 

بابت سورس برنامه ممنونم... :)
اینم باید تریس کنم با بفهمم چی به چیه...

----------


## Ananas

توضیحش اینه که ماتریسم رو آرایه ای یک بعدی گرفتم با تعداد اعضای N * N که فرض بر اینه که ردیف های ماتریس پشت سر هم قرار دارن. و برای راحتیه دسترسی یک تابع نوشتم که اندیس i, j و تعداد ستون ها رو میگیره و اندیس لازم برای آرایه ی یک بعدی رو میده. تابع :GetIndex . حالا تو تابع main میام یک حافظه به عنوان ماتریس میگیرم بعد تو یک حلقه تمام اعضای اون رو مقدار اولیه میدم. حالا باید اعضایی رو که لوزی رو میسازن مقدار دهی کنیم. در تابعی که این کار رو میکنه تو یک حلقه که در واقع از سمت چپ ماتریس (ستون اول) شروع میشه تا سمت راست ماتریس (ستون آخر) پیش میره و در هر ستون دو عضو هست که باید تغییر بده. یکی بالا و یکی قرینه اش پایین. و بعد هم که ماتریس چاپ میشه.

----------


## ali chegini

برای درست کردن ماتریس چند تا راه بود :
1- یه کلاس بنویسیم و تمام اپراتورها رو پیاده سازی کنیم.
2-از آرایه اشاره گر دوبعدی استفاده کنیم مثل زیر :
int **matrix=new (int*) matrix[]
3- از روش ananas استفاده کنی مثل زیر :
char * pMatrix = (char *)malloc(sizeof(char) * N * N);
4- از کلاس وکتور استفاده کنی.به موارد زیر مراجعه کن.
http://www.cplusplus.com/reference/vector/vector/
می تونی تو کتاب آموزش مبانی کامپیوتر و برنامه نویسی به زبان C++‎ نوشته (علی دهقان - دکتر ناصر قاسم آقایی و مهدی جابرزاده انصاری) صفحه 264

----------

