PDA

View Full Version : ماتریس



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

http://upload7.ir/images/58549282347530721338.png

سپاس

nokhodi
چهارشنبه 06 آذر 1392, 23:13 عصر
به غیر رابطه عددی که اثرا توی برنامه های ماتریس استفاده میشه( و من هنوز توی این مثال نتونستم بفهممش)

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

ali chegini
جمعه 08 آذر 1392, 01:48 صبح
سلام.شاید این ایده خوبی باشه.
113325

aminsaeedi
جمعه 08 آذر 1392, 09:13 صبح
به نظرم این جواب نمیده چون وقتی ما خط چهارم رو چاپ کنیم دیگه به خط های قبلی دسترسی نداریم

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

Ananas
جمعه 08 آذر 1392, 11:36 صبح
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
جمعه 08 آذر 1392, 11:43 صبح
و یا :

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
جمعه 08 آذر 1392, 11:48 صبح
دوست عزیز نمی خواهید این هارو توضیح بدهید

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

aminsaeedi
جمعه 08 آذر 1392, 13:18 عصر
مرکز در ردیف اول از تقسیم تعداد ستون بر ۲ و در کل +۱ بدست میاد نه فقط تقسیم بر ۲خالی

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

ali chegini
یک شنبه 10 آذر 1392, 00:51 صبح
اگه بخوای کل آرایه رو پیمایش کنی تو حالت 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
یک شنبه 10 آذر 1392, 00:57 صبح
به جز حلقه آخر که برای نمایش ماترس هست و میتونی حذفش کنی.
4 تا حلقه داریم که n/2 بار اجرا میشه و میشه 4 ضربدر n/2 که میشه 2n

nokhodi
یک شنبه 10 آذر 1392, 13:43 عصر
اگه بخوای کل آرایه رو پیمایش کنی تو حالت 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;
}

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

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


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

Ananas
یک شنبه 10 آذر 1392, 15:04 عصر
گر 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
یک شنبه 10 آذر 1392, 17:50 عصر
نقل قول ( برنامه شما رو و اون خط اولی که گفتید رو که N*N نمیشه رو اینا رو متوجه نشدم...میشه لطفا بیشتر توضیح بدین... )
بهش میگن پیچیدگی زمانی . اینا رو ببین :
http://fa.wikipedia.org/wiki/%D8%B2%D9%85%D8%A7%D9%86_%D8%A7%D8%AC%D8%B1%D8%A7% DB%8C_%D8%A7%D9%84%DA%AF%D9%88%D8%B1%DB%8C%D8%AA%D 9%85
http://fa.wikipedia.org/wiki/%D9%BE%DB%8C%DA%86%DB%8C%D8%AF%DA%AF%DB%8C_%D8%B2% D9%85%D8%A7%D9%86%DB%8C

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

روش آخر Ananas (http://barnamenevis.org/member.php?233990-Ananas) هم جالبه . ممنون Ananas (http://barnamenevis.org/member.php?233990-Ananas)

nokhodi
یک شنبه 10 آذر 1392, 23:16 عصر
در مورد هدر vector هم میشه یه توضیح بدین?
برنامه شما بدون مشکل اجرا شد...

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


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

Ananas
دوشنبه 11 آذر 1392, 01:35 صبح
#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
دوشنبه 11 آذر 1392, 13:42 عصر
Ananas عزیز

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

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

ali chegini
دوشنبه 11 آذر 1392, 14:18 عصر
برای درست کردن ماتریس چند تا راه بود :
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