PDA

View Full Version : ایجاد آرایه 2 بعدی دینامیک با طول متغیر در ++C



amini2016
چهارشنبه 25 آذر 1394, 15:57 عصر
سلام

بنده برای ایجاد یک برنامه سی ++ که در اون طول آرایه 2 بعدی در طی اجرای برنامه تغییر می کنه دچار مشکل شدم

ارایه 2 بعدی رو به شکل زیر ایجاد میکنم:


int main(){
int n;
int **a=new int*[n];
n=10;
for(int i=0;i<n;i++)
a[i]=new int[n];

for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
a[i][j]=(i+1)*(j+1);

for(int i=0;i<n;i++){
for(int j=0;j<n;j++)
cout<<a[i][j]<<'\t';
cout<<endl;
}
a[11][1]=222;
cout<<a[11][1]<<"\n";
for(int i=0; i<n;i++)
delete [] a[i];
delete [] a;
}

بدون خط 17 و 18 برنامه بدون مشکل عمل می کنه ولی تمام چیزی که از برنامه میخوام اینه که بعد از شروع برنامه بتونم داده هایی که جدید ایجاد میشه رو تو همون آرایه قبلی اضافه کنم که خط 17 و 18 مثال اون هست. حتی برای یک سطر کامل هم امتحان کردم و نشد. پیام خطا هم در تصویر پیوست شده. نرم افزار هم code blocks هست نسخه 13.12
یک سوال دیگه هم دارم، در سی++ وقتی یک ارایه یک بعدی تعریف میکنیم این آرایه به صورت سطری شکل میگیره یا ستونی؟ وقتی آرایه دو بعدی تعریف میکنیم ، اولین بعد سطر هست یا ستون؟ این سوال ها با توجه به اینکه اینها در متلب پاسخ مشخصی داره برام پیش اومده.
متشکرم

تصویر پیام در خروجی
137479

Poores
یک شنبه 29 آذر 1394, 01:49 صبح
اول اینکه شما متغیر n رو مقدار اولیه ندادین و بعدش به اندازه n آرایه دو بعدی ساختین که متناقضه ، پس باید جای خط 4 و 3 عوض بشه.

int n = 10 ;

int **a=new int*[n];

دوم منظور شمارو از "تمام چیزی که از برنامه میخوام اینه که بعد از شروع برنامه بتونم داده هایی که جدید ایجاد میشه رو تو همون آرایه قبلی اضافه کنم" متوجه نمیشم اما چیزی که دقیقا مشخصه اینه که شما قصد دارین به سطر 11 ام یک آرایه 10 سطری دسترسی پیدا کنین ! که طبیعتا با ارور مواجه میشین و اونم به این خاطر که سطر 11 اصلا وجود نداره که بخواد در ستون 1امش عدد 222 ریخته بشه!

آرایه پویا آرایه ای نیست که در طول برنامه بشه سایزشو تغییر داد! در واقع تنها مزیت آرایه پویا (داینامیک) نسبت به آرایه معمولی این هست که می تونیم سایز آرایه پویا رو در طی برنامه مشخص کنیم (یک بار مشخص می شود و دیگر قابل تغییر نخواهد بود).

int n;
cin >> n;
int *a = new int[n];


اما اگر در برنامه شما سایز آرایه طوری نیست که از ابتدا مشخص باشه چند راه دارین :
1- سایز آرایتون رو ماکزیموم در نظر بگیرید ، یعنی فکر کنید که حد اکثر چند خانه از آرایه لازم دارید و به همان مقدار آرایه را تعریف کنید.
2- از لیست پیوندی استفاده کنید ، که سایزش به راحتی زیاد و کم میشه ! اما مشکلی که داره ، مشکل زمان هست! لیست های پیوندی پیچیدگی زمانی بالایی دارند که اگر برایتان مهم هست ازین مورد صرف نظر کنید.
3- استفاده از Vector ها که تقریبا به صرفه ترین راه هست.

درمورد سوال آخر ،
وقتی آرایه یک بعدی تعریف میشه ، چه سطری در نظر بگیرید چه ستونی فرقی ندارند اما معمولا سطری در نظر میگیرن (شما هرطور که میخواهید از آرایه یک بعدی استفاده کنین)
در مورد آرایه دو بعدی هم همینطور ، بستگی داره شما چطور بهش نگاه کنید اما معمولا بعد اول سطر و بعد دوم ستون در نظر گرفته میشه (واسه درک بهتر همین طوری در نظر بگیرید)

menosoft
دوشنبه 30 آذر 1394, 16:38 عصر
اول اینکه شما متغیر n رو مقدار اولیه ندادین و بعدش به اندازه n آرایه دو بعدی ساختین که متناقضه ، پس باید جای خط 4 و 3 عوض بشه.

int n = 10 ;

int **a=new int*[n];

دوم منظور شمارو از "تمام چیزی که از برنامه میخوام اینه که بعد از شروع برنامه بتونم داده هایی که جدید ایجاد میشه رو تو همون آرایه قبلی اضافه کنم" متوجه نمیشم اما چیزی که دقیقا مشخصه اینه که شما قصد دارین به سطر 11 ام یک آرایه 10 سطری دسترسی پیدا کنین ! که طبیعتا با ارور مواجه میشین و اونم به این خاطر که سطر 11 اصلا وجود نداره که بخواد در ستون 1امش عدد 222 ریخته بشه!

آرایه پویا آرایه ای نیست که در طول برنامه بشه سایزشو تغییر داد! در واقع تنها مزیت آرایه پویا (داینامیک) نسبت به آرایه معمولی این هست که می تونیم سایز آرایه پویا رو در طی برنامه مشخص کنیم (یک بار مشخص می شود و دیگر قابل تغییر نخواهد بود).

int n;
cin >> n;
int *a = new int[n];


اما اگر در برنامه شما سایز آرایه طوری نیست که از ابتدا مشخص باشه چند راه دارین :
1- سایز آرایتون رو ماکزیموم در نظر بگیرید ، یعنی فکر کنید که حد اکثر چند خانه از آرایه لازم دارید و به همان مقدار آرایه را تعریف کنید.
2- از لیست پیوندی استفاده کنید ، که سایزش به راحتی زیاد و کم میشه ! اما مشکلی که داره ، مشکل زمان هست! لیست های پیوندی پیچیدگی زمانی بالایی دارند که اگر برایتان مهم هست ازین مورد صرف نظر کنید.
3- استفاده از Vector ها که تقریبا به صرفه ترین راه هست.

درمورد سوال آخر ،
وقتی آرایه یک بعدی تعریف میشه ، چه سطری در نظر بگیرید چه ستونی فرقی ندارند اما معمولا سطری در نظر میگیرن (شما هرطور که میخواهید از آرایه یک بعدی استفاده کنین)
در مورد آرایه دو بعدی هم همینطور ، بستگی داره شما چطور بهش نگاه کنید اما معمولا بعد اول سطر و بعد دوم ستون در نظر گرفته میشه (واسه درک بهتر همین طوری در نظر بگیرید)

برای تکمیل سخنان جناب Poores می تونید از کد زیر استفاده کنید اما همانطور که فرمودند بهترین گزینه استفاده از وکتور می باشد.
این یک برای ساخته یک شبکه در cfd استفاده شده است که به صورت ساده شده اینجا قرارش دادم.


#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;

struct coordinate
{
double x;
double y;
};

int main()
{
double x1=-5,x2=5;
double y1=-5,y2=5;
int nx=5;
int ny=5;
int i, j;

double delx = (x2-x1)/nx;
double dely = (y2-y1)/ny;
coordinate **Point;

Point = new coordinate*[nx+1];

for(i = 0; i < nx+1; i++)
{
Point[i]= new coordinate [ny+1];
}

for(i = 0; i < nx+1; i++)
{
for(j = 0; j < ny+1; j++)
{
Point[i][j].x = x1+i*delx;
Point[i][j].y = y1+j*delx;

cout << i<<" " <<j<< " " <<Point[i][j].x<<" "<< Point [i][j].y <<endl;
}
}

cout << Point[1][10].x;

for(int i=0; i<nx;i++)
{
delete [] Point[i];
}

delete Point;


}

amini2016
جمعه 04 دی 1394, 00:48 صبح
اما اگر در برنامه شما سایز آرایه طوری نیست که از ابتدا مشخص باشه چند راه دارین :
1- سایز آرایتون رو ماکزیموم در نظر بگیرید ، یعنی فکر کنید که حد اکثر چند خانه از آرایه لازم دارید و به همان مقدار آرایه را تعریف کنید.
2- از لیست پیوندی استفاده کنید ، که سایزش به راحتی زیاد و کم میشه ! اما مشکلی که داره ، مشکل زمان هست! لیست های پیوندی پیچیدگی زمانی بالایی دارند که اگر برایتان مهم هست ازین مورد صرف نظر کنید.
3- استفاده از Vector ها که تقریبا به صرفه ترین راه هست.


سلام
متشکرم
البته به صورت یک بعدی آرایه ای با طول نامشخص و قابل تغییر در طی برنامه تعریف کردم و بدون ارور برنامه کار کرد (با استفاده از اشاره گر) اما برای 2 بعدی نشد
این برای حالت یک بعدی:


[CODE]
#include <iostream>
#include <fstream>
#include <conio.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
using namespace std;
int main(){
int i,j,k,xnod=5,ynod=5;
int v_edgnum=2,h_edgnum=2,ed=v_edgnum*2+h_edgnum*2;
//int n; // Dynamic memory
//cin >> n;
//double arr[ n ];
int n; // 1D
double *arr;
//cin >> n;
arr = new double [ n ];
for(i=1;i<ed+1;i++){
arr[i]=i*2;
cout<<"arr["<<i<<"] is: "<<arr[i]<<"\n";
}
cout<<"= = = = = = = =\n";
arr[8]=2.5;
arr[9]=-4;
cout<<"arr["<<8<<"] is: "<<arr[8]<<"\n";
cout<<"arr["<<9<<"] is: "<<arr[9]<<"\n";
delete[ ] arr;
}

[CODE]
توی متلب این کار به راحتی انجام میشه اما افسوس که در سی ++ نمیشه؛ فکر کنم باید برم سراغ بردار
به هر حال از پاسخ شما ممنونم

جناب menosoft از پاسخ شما و کدی که قرار دادید هم خیلی متشکرم

zero_ox
جمعه 04 دی 1394, 09:27 صبح
#include <iostream>


using namespace std;


int main()
{
int r,c,i,j;
cout<<"row:";
cin>>r;
cout<<"col:";
cin>>c;
cout<<"-----------------------------------------\n";
int **a=new int*[r];
for(i=0;i<r;i++){
a[i]=new int[c];
for(j=0;j<c;j++){
cout<<":";
cin>> a[i][j];}}
cout<<"-----------------------------------\n";


for(i=0;i<r;i++){
for(j=0;j<c;j++)


cout<<"a["<<i<<"]["<<j<<"] :"<<*(*(a+i)+j)<<"\t";
cout<<endl;
}
return 0;
}

rahnema1
جمعه 04 دی 1394, 23:24 عصر
سلام
این تاپیک (http://barnamenevis.org/showthread.php?445461) را مشاهده کنید که یک نمونه آرایه دو بعدی با وکتور هست
مثلا یک ماتریس ایجاد می کنیم به ابعاد 10 در 10

int cols = 10;
int rows = 10;
matrix mat(rows,vec(cols));

بعد به این صورت یک سطر بهش اضافه می کنیم:
mat.push_back(vec(cols));
این هم مقداردهی یک خانه
mat[10][0] = 222;
البته توی کد شما عدد 11 گذاشتید اما چون ما ده تا سطر داشتیم به شماره 0 تا 9 بنابراین یک سطر که اضافه بشه شماره اش می شه 10 نه 11
دقت کنید با متلب فرق می کنه اینجا اندیسها از صفر شروع می شه ولی در متلب از 1