آرایه های 2 بعدی!

Mili+

New Member
وقتتون بخیر! :rose:

یه سوال بهم داده شده و من تو چندتا نُکتش مشکل داشتم ممنون میشم کمکم کنید!!

سوال: برنامه ای بنویسید که یک آرایه 2 بعدی بطول n و k تعریف کرده و بعد آنرا مقدار دهی کنید، سپس یک کلید از ورودی دریافت کرده و مشخص کنید که این کلید در آرایه وجود دارد یا خیر!!!

برنامه ای که من نوشتم:




[CPPS]#include<iostream.h>
#include<conio.h>
#define n 3
#define k 2
void main () {
int i,j;
float x [n] [k];
for (i = 0 ; i < n ; i++)
for (j = 0 ; j < n ; j++)
{
cin>> x [j];
}
float key;
cout<< "lotfan kelid ra vared konid: "<<endl;
cin>> key ;
for (i = 0 ; i < n ; i++)
for (j = 0 ; j < n ; j++)
{
if (x [j] == key)
{
cout<<...................

break;
}
}
if (i == n , j == k)
cout<< "key yaft nashod!" << endl;
cout<< "Prees Any Key To Exit........" << endl;

getch ();}[/CPPS]



سوال های من اینه:

1) شکل کلی دستوری که نوشتم تا چه حد درسته؟
اشتباهاتمو لطفا بگید!

2) اون cout که نقطه گذاشتم، دقیقا چیو باید cout کنم؟ x یا [j] رُ
ممنون میشم یه کوچولو توضیح بدید!

3) اون if آخر درسته؟ یا اشتباس شرطم؟

4) استفاده از break درسته؟؟

5) اینکه 2 تا float تعریف کردم مشکلی ایجاد نمیکنه؟؟
 
آخرین ویرایش:

the_king

مدیرکل انجمن
وقتتون بخیر! :rose:

یه سوال بهم داده شده و من تو چندتا نُکتش مشکل داشتم ممنون میشم کمکم کنید!!

سوال: برنامه ای بنویسید که یک آرایه 2 بعدی بطول n و k تعریف کرده و بعد آنرا مقدار دهی کنید، سپس یک کلید از ورودی دریافت کرده و مشخص کنید که این کلید در آرایه وجود دارد یا خیر!!!

برنامه ای که من نوشتم:




[CPPS]#include<iostream.h>
#include<conio.h>
#define n 3
#define k 2
void main () {
int i,j;
float x [n] [k];
for (i = 0 ; i < n ; i++)
for (j = 0 ; j < n ; j++)
{
cin>> x [j];
}
float key;
cout<< "lotfan kelid ra vared konid: "<<endl;
cin>> key ;
for (i = 0 ; i < n ; i++)
for (j = 0 ; j < n ; j++)
{
if (x [j] == key)
{
cout<<...................

break;
}
}
if (i == n , j == k)
cout<< "key yaft nashod!" << endl;
cout<< "Prees Any Key To Exit........" << endl;

getch ();}[/CPPS]



سوال های من اینه:

1) شکل کلی دستوری که نوشتم تا چه حد درسته؟
اشتباهاتمو لطفا بگید!

2) اون cout که نقطه گذاشتم، دقیقا چیو باید cout کنم؟ x یا [j] رُ
ممنون میشم یه کوچولو توضیح بدید!

3) اون if آخر درسته؟ یا اشتباس شرطم؟

4) استفاده از break درسته؟؟

5) اینکه 2 تا float تعریف کردم مشکلی ایجاد نمیکنه؟؟


بهتره که از void main اجتناب کنید :
کد:
void main()
{
    .
    .
    .
}
کد اشتباهی نیست، اما مشکل ناسازگاری بوجود میاره، چون با استاندارد زبان مطابقت نداره و برخی کامپایلر ها که به استاندارد پایبند اند قبولش نمی کنند.
بهتره بجای void main از int main و return 0 در انتهای کد استفاده کنید :
کد:
int main()
{
    .
    .
    .
    return 0;
}

حلقه j که برای اندیس دوم آرایه نوشته اید باید بر اساس k باشه، نه n ، پس باید بجای شرط j < n از j < k استفاده کنید :
کد:
    for (i = 0; i < n; i++)
        for (j = 0; [B][COLOR="#0000FF"]j < k[/COLOR][/B]; j++)
        {
            cin >> x[i][j];
        }

کد:
    for (i = 0; i < n; i++)
        for (j = 0; [B][COLOR="#0000FF"]j < k[/COLOR][/B]; j++)
            {
                if (x[i][j] == key)
                {

صورت مساله صرفا به یک جواب یافت شد یا یافت نشد احتیاج دارد. پس مهم این است که بدانیم دو حلقه تو در تو به چه علت خاتمه می یابند،
به علت رسیدن به انتهای آرایه یا به دلیل پیدا شدن یک key در بین خانه های آرایه.
زمانی که شما از break استفاده می کنید، از داخلی ترین حلقه ای که break در آن قرار داره خارج می شود.
اگر دو حلقه for تو در تو داشته باشید، نوشتن break در داخل حلقه دوم، صرفا از داخل حلقه دوم خارج اش می کند، نه حلقه اول.
به عنوان مثال ترکیب break در کد زیر صحیح نیست، پیغامی شبیه به !key yaft shod ممکن است بیش از یکبار نمایش داده شود که مطلوب نخواهد بود :
کد:
    for (i = 0; i < n; i++)
        for (j = 0; j < k; j++)
            {
                if (x[i][j] == key)
                {
[B][COLOR="#0000FF"]                    cout << "key yaft shod!" << endl;[/COLOR][/B]
                    break;
                }
            }
ممکن است در آرایه در چهار سطر مقدار تکراری key وجود داشته باشد، آنگاه برای هر کدام از آن چهار سطر یکبار پیغام نمایش داده می شود.

شاید بهتر باشد که فقط break انجام شود و نمایش پیغام را به بعد از حلقه اول موکول کنیم :
کد:
    for (i = 0; i < n; i++)
        for (j = 0; j < k; j++)
            {
                if (x[i][j] == key)
                {
                    break;
                }
            }
    if ((i == n) && (j == k))        
        cout << "key yaft nashod!" << endl;
    else
        cout << "key yaft shod!" << endl;
به نحوه نوشتن صحیح شرط i == n و j == k در کد بالا توجه کنید.
اما این کد بالا هم ایراد دارد، چون break نمی تواند روی اجرای حلقه اول تاثیر بگذارد. break صرفا می تواند حلقه دوم را پایان دهد.
اگر key در سطر آخر آرایه موجود نباشد، پیغام !key yaft nashod نمایش داده می شود، حتی اگر key در سطر های قبلی پیدا شده باشد.

از آنجایی که دو حلقه for تو در تو داریم، بجای اینکه روی break تکیه کنیم مقدار یک متغیر دیگر را مبنا قرار می دهیم :
کد:
[B][COLOR="#0000FF"]    int found = 0;[/COLOR][/B]
    for (i = 0; i < n; i++)
        for (j = 0; j < k; j++)
            {
                if (x[i][j] == key)
                {
[B][COLOR="#0000FF"]                    found = 1;[/COLOR][/B]
                    break;
                }
            }
[B][COLOR="#0000FF"]    if (found == 0)        [/COLOR][/B]
        cout << "key yaft nashod!" << endl;
    else
        cout << "key yaft shod!" << endl;

نوشتن آن break الزامی نیست، چون صرفا روی سرعت اجرای کد تاثیر دارد، ما فقط بر اساس مقدار found تصمیم خواهیم گرفت.
می توانیم شرط حلقه اول را طوری تغییر دهیم که اگر key در سطر قبلی پیدا شد، دیگر به جستجو ادامه ندهد :
کد:
    int found = 0;
    for (i = 0; [B][COLOR="#0000FF"](i < n) && (found == 0)[/COLOR][/B]; i++)
        for (j = 0; j < k; j++)
            {
                if (x[i][j] == key)
                {
                    found = 1;
                    break;
                }
            }
    if (found == 0)
        cout << "key yaft nashod!" << endl;
    else
        cout << "key yaft shod!" << endl;

کد:
#include <iostream>
#include <conio.h>

using namespace std;

#define n 3
#define k 2

int main()
{
    int i,j;
    float x[n][k];
    for (i = 0; i < n; i++)
        for (j = 0; j < k; j++)
        {
            cin >> x[i][j];
        }
    float key;
    cout << "lotfan kelid ra vared konid: " << endl;
    cin >> key ;
    int found = 0;
    for (i = 0; (i < n) && (found == 0); i++)
        for (j = 0; j < k; j++)
            {
                if (x[i][j] == key)
                {
                    found = 1;
                    break;
                }
            }
    if (found == 0)
        cout << "key yaft nashod!" << endl;
    else
        cout << "key yaft shod!" << endl;
    cout << "Press Any Key To Exit........" << endl;
    getch();
    return 0;
}
 

Mili+

New Member
کد اشتباهی نیست، اما مشکل ناسازگاری بوجود میاره، چون با استاندارد زبان مطابقت نداره و برخی کامپایلر ها که به استاندارد پایبند اند قبولش نمی کنند.
بهتره بجای void main از int main و return 0 در انتهای کد استفاده کنید :
متوجه شدم، فقط میشه بگید کدوم کامپلیرها به این موضوع حساسند و مهمه این قسمت؟

حلقه j که برای اندیس دوم آرایه نوشته اید باید بر اساس k باشه، نه n ، پس باید بجای شرط j < n از j < k استفاده کنید :
بله درسته، اشتباه تایپی بوده :rose:


صورت مساله صرفا به یک جواب یافت شد یا یافت نشد احتیاج دارد. پس مهم این است که بدانیم دو حلقه تو در تو به چه علت خاتمه می یابند،
به علت رسیدن به انتهای آرایه یا به دلیل پیدا شدن یک key در بین خانه های آرایه.
زمانی که شما از break استفاده می کنید، از داخلی ترین حلقه ای که break در آن قرار داره خارج می شود.
اگر دو حلقه for تو در تو داشته باشید، نوشتن break در داخل حلقه دوم، صرفا از داخل حلقه دوم خارج اش می کند، نه حلقه اول.
به عنوان مثال ترکیب break در کد زیر صحیح نیست، پیغامی شبیه به !key yaft shod ممکن است بیش از یکبار نمایش داده شود که مطلوب نخواهد بود
ممکن است در آرایه در چهار سطر مقدار تکراری key وجود داشته باشد، آنگاه برای هر کدام از آن چهار سطر یکبار پیغام نمایش داده می شود.
بله متوجه شدم، اما این قسمتُ اصلا بهمون یاد آور نشده بودن
درست میگید :rose:


به نحوه نوشتن صحیح شرط i == n و j == k در کد بالا توجه کنید.
بله ممنون، متوجه اشتباه نوشتنم تو کد شدم! :rose:


اما این کد بالا هم ایراد دارد، چون break نمی تواند روی اجرای حلقه اول تاثیر بگذارد. break صرفا می تواند حلقه دوم را پایان دهد.
اگر key در سطر آخر آرایه موجود نباشد، پیغام !key yaft nashod نمایش داده می شود، حتی اگر key در سطر های قبلی پیدا شده باشد.

متوجه این قسمت نشدم!!
مگه برنامه خط به خط خونده نمیشه؟؟
چرا اگه تو سطر اول باشه key باز یافت نشد نشون میده؟
break یا continue باشه فرقی نداره؟؟ شکل کلی ایراد داره؟؟

از آنجایی که دو حلقه for تو در تو داریم، بجای اینکه روی break تکیه کنیم مقدار یک متغیر دیگر را مبنا قرار می دهیم :
نوشتن آن break الزامی نیست، چون صرفا روی سرعت اجرای کد تاثیر دارد، ما فقط بر اساس مقدار found تصمیم خواهیم گرفت.
حالا اگه بخوایم بدون مبنای جدید و بر اساس همون break یا continue پیش بریم چطور؟
اونوقت به چه صورت میشه؟


می توانیم شرط حلقه اول را طوری تغییر دهیم که اگر key در سطر قبلی پیدا شد، دیگر به جستجو ادامه ندهد :

اینم متوجه شدم ، ممنون :rose:
 

the_king

مدیرکل انجمن
متوجه شدم، فقط میشه بگید کدوم کامپلیرها به این موضوع حساسند و مهمه این قسمت؟
mingw و gcc و ...
[/QUOTE]

متوجه این قسمت نشدم!!
مگه برنامه خط به خط خونده نمیشه؟؟
چرا اگه تو سطر اول باشه key باز یافت نشد نشون میده؟
break یا continue باشه فرقی نداره؟؟ شکل کلی ایراد داره؟؟
در این مورد continue رو کلا فراموش کنید، ما می خواهیم وقتی مقدار key پیدا شد، سریعتا به جستجو خاتمه بدهیم.
هدف اینه که سریعا از حلقه های تو در توی جستجو خارج شویم. break در این مورد ناقص عمل می کنه ولی کارش بی ربط نیست، break میگه از یک حلقه جستجو خارج شو.
از اونجایی که break فقط روی یک حلقه تاثیر داره، (از حلقه داخلی، نه از هر دو حلقه تو در تو) نمی تونه راه حل مساله ما باشه.
کاربرد continue اصلا با مساله ما جور در نمیاد، continue میگه فورا برو سراغ ادامه جستجو. اینجا continue هیچ نقش مفیدی نمی تونه داشته باشه.

یک مثال می زنم که ببینید یک break به تنهایی چرا کمکی نمی کنه. فرض کنیم یک آرایه دارید که در حال جستجو برای key ئه. حلقه اول بر اساس شماره سطر (اندیس اول)
پیمایش می کنه و حلقه دوم که داخل حلقه اول قرار گرفته بر اساس شماره ستون (اندیس دوم) پیمایش می کنه. break اگر در حلقه اول نوشته بشه به جستجو خاتمه میده
(چون از حلقه اول خارج میشه) و اگر در حلقه دوم نوشته بشه، به جستجو در سطر فعلی (که در حال جستجو ئه) خاتمه میده، (چون فقط از حلقه دوم که داخل حلقه اول ئه خارج میشه)

فرضا الان تا وسط آرایه جستجو انجام شده. درست در وسط آرایه به مقدار key بر می خورید و در داخل حلقه دوم که داخلی تره break می کنید.
break مورد نظر چیکار می کنه؟ به حلقه دوم خاتمه می ده، چون این حلقه داخل حلقه اول قرار گرفته، شماره سطر یک واحد افزایش پیدا می کنه و جستجو در سطر های
بعدی از اولین ستون تا آخرین ستون ادامه پیدا می کنه...
تنها کاری که این break انجام میده اینه که در اون سطر که در حال جستجو بود، ستون های بعدی جستجو نمی شوند، کاری به سطر های بعدی نداره.
 

Mili+

New Member

مرسی :rose:



در این مورد continue رو کلا فراموش کنید، ما می خواهیم وقتی مقدار key پیدا شد، سریعتا به جستجو خاتمه بدهیم.
هدف اینه که سریعا از حلقه های تو در توی جستجو خارج شویم. break در این مورد ناقص عمل می کنه ولی کارش بی ربط نیست، break میگه از یک حلقه جستجو خارج شو.
از اونجایی که break فقط روی یک حلقه تاثیر داره، (از حلقه داخلی، نه از هر دو حلقه تو در تو) نمی تونه راه حل مساله ما باشه.
کاربرد continue اصلا با مساله ما جور در نمیاد، continue میگه فورا برو سراغ ادامه جستجو. اینجا continue هیچ نقش مفیدی نمی تونه داشته باشه.

تا اینجاشو متوجه شدم.



یک مثال می زنم که ببینید یک break به تنهایی چرا کمکی نمی کنه. فرض کنیم یک آرایه دارید که در حال جستجو برای key ئه. حلقه اول بر اساس شماره سطر (اندیس اول)
پیمایش می کنه و حلقه دوم که داخل حلقه اول قرار گرفته بر اساس شماره ستون (اندیس دوم) پیمایش می کنه. break اگر در حلقه اول نوشته بشه به جستجو خاتمه میده
(چون از حلقه اول خارج میشه) و اگر در حلقه دوم نوشته بشه، به جستجو در سطر فعلی (که در حال جستجو ئه) خاتمه میده، (چون فقط از حلقه دوم که داخل حلقه اول ئه خارج میشه)

تا اینجاشم ok
اما یه سوال، با این وصف نمیشه برا هر حلقه break جدا نوشت؟
امکان نوشتن 2 تا break وجود نداره؟
چون break نمیتونه 2 تا حلقه رُ پوشش بده و بعد هر حلقه که نوشته شه فقط تو همون عمل میکنه! درسته ؟

فرضا الان تا وسط آرایه جستجو انجام شده. درست در وسط آرایه به مقدار key بر می خورید و در داخل حلقه دوم که داخلی تره break می کنید.
break مورد نظر چیکار می کنه؟ به حلقه دوم خاتمه می ده، چون این حلقه داخل حلقه اول قرار گرفته، شماره سطر یک واحد افزایش پیدا می کنه و جستجو در سطر های
بعدی از اولین ستون تا آخرین ستون ادامه پیدا می کنه...
تنها کاری که این break انجام میده اینه که در اون سطر که در حال جستجو بود، ستون های بعدی جستجو نمی شوند، کاری به سطر های بعدی نداره.


اینم متوجه شدم، ممنون



حالا اگه بدون اون مبنایی که شما نوشتید بخوام بنویسم امکانش نیست و ممکنه برنامه درست عمل نکنه! درسته؟؟
بدون اون مبنا % خطا بالاست؟

بعلت همون break صرفا می تواند حلقه دوم را پایان دهد.؟؟
 

جدیدترین ارسال ها

بالا