پیمایش آرایه های دو بعدی بصورت مورب - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

پیمایش آرایه های دو بعدی بصورت مورب

+1 امتیاز
با سلام.
 
در ویژوال بیسیک 6 یک نوع حرکت یا پیمایش خاص داشتم می خواستم سوال بپرسم از شما که چطوری میشه اونو انجام داد؟
 
من یک آرایه دو بعدی نوشتم که مثلا توسط کد زیر به صورت مارپیچ در آن پیمایش می کنم:
 
Dim A() As Integer
Dim M As Integer, N As Integer
Private Sub cmdCreate_Click()
M = txtM
N = txtN
ReDim A(M, N) As Integer
End Sub

Private Sub cmd1_Click()
Dim T As Integer
M=3
N=5
For i = 1 To M
    If i Mod 2 = 1 Then
        For j = 1 To N
            T = T + 1
            A(i, j) = T
        Next
    Else
        For j = N To 1 Step -1
            T = T + 1
            A(i, j) = T
        Next
    End If
Next
End Sub

Private Sub cmdOutput_Click()
Cls
For i = 1 To M
    For j = 1 To N
            Print A(i, j),
    Next
    Print: Print
Next
End Sub

 

 
خروجی:
 
1   2   3   4   5
10  9   8   7   6
11  12  13  14  15

 

 
حالا من می خوام به صورت زیر پیمایش کنه. اسمش هم نفهمیدم چیه! این مدل به صورت زیر است:
1 2 4 7 10
3 5 8 11 13
6 9 12 14 15

 

اگه توجه کنید یک حالت خطی مورب داره که نمی دونم حلقه اش را چطوری بنویسم. فقط فکر نکنید این مدل ها را به هم ریخته و اشتباه نوشتم! فقط شما باید آنها را به ترتیب اعداد بخوانید. از 1 تا 15.
 
 
ممنون میشم راهنمایی کنید این دو مدل را چطوری پیاده کنم.
 
 
با تشکر.
سوال شده دی 5, 1392  بوسیله ی mahdi.manian (امتیاز 56)   3 8 12
دوباره تگ گذاری شد بهمن 22, 1392 بوسیله ی BlueBlade

5 پاسخ

+2 امتیاز
 
بهترین پاسخ

کد کامل

#include <iostream>

using namespace std;

int main()
{
    int num =1;
    int a[7][5];
   //mosalas bala
    for(int i=0;i<5;i++)
    {
        int k=i;
        for(int j=0;j<7;j++)
        {
            a[j][k]=num;
            num++;
            k--;
            if(k<0)
                break;

        }
    }

    //mosalas payeen
     num =5 * 7 ;
    for(int i=4;i>=0;i--)
    {
        int k=i;
        for(int j=6;j>=0;j--)
        {
            a[j][k]=num;
            num--;
            k++;
            if(k>4)
                break;

        }
    }
     //ghotr matris----- agar tedad satr ha zoj bashe be in for niazy nist
     for(int i=5,j=0;i>0;i--,j++)
     {
         a[i][j]=num;
         num--;
     }
     
    for(int i=0;i<7;i++)
    {
        for(int j=0;j<5;j++)
          cout<<a[i][j]<<"  ";
        cout<<endl;
    }

    return 0;
}

 

کد vb

Module Module1

    Sub Main()
        Dim a(7, 5) As Integer
        Dim num As Integer
        Dim k As Integer

        num = 1

        For i = 0 To 4
            k = i

            For j = 0 To 7
                a(j, k) = num
                num = num + 1
                k = k - 1
                If k < 0 Then Exit For
            Next
        Next

        num = 35

        For i = 4 To 0 Step -1
            k = i
            For j = 6 To 0 Step -1
                a(j, k) = num
                num = num - 1
                k = k + 1
                If k > 4 Then Exit For
            Next
        Next

        Dim ii As Integer
        ii = 0
        For i = 5 To 0 Step -1
            a(i, ii) = num
            num = num - 1
            ii = ii + 1
        Next


        For i = 0 To 6
            For j = 0 To 4
                MsgBox(a(i, j))
            Next
        Next
    End Sub

End Module

 

پاسخ داده شده دی 7, 1392 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
انتخاب شد دی 7, 1392 بوسیله ی mahdi.manian
کد vb رو هم اضافه کردم
ممنون عالی بود. مشکلم حل شد. بازم ممنون.
+2 امتیاز

هر چقدر فکر کردم راهی به ذهنم نرسید که کمتر از یک هفته مونده به سال ۲۰۱۴ یک برنامه از سال ۱۹۹۸ رو پیدا کنم و نصب کنم و براش کد بنویسم.

به زبان C جواب میدم.

void indexTransform(int lena, int lenb, int index, int* indexa, int* indexb) {
	int lenl = lena;
	if(lenl < lenb)
		lenl = lenb;
	int tril = (lenl * (lenl - 1)) / 2;
	if(index > tril) {
		index -= tril;
		*indexa = lenl + (index / tril);
		*indexb = index % tril;
	} else {
		for(int n = 1;n != lenl;n++) {
			if (index > lenl) {
				index -= n;
			} else {
				*indexa = n;
				*indexb = index;
			}
		}
	}
	*indexa -= *indexb;
}

این کد به هیچ عنوان تست نشده و ممکنه درست عمل نکنه ولی حداقل بهتون ایده میده.

پاسخ داده شده دی 5, 1392 بوسیله ی FastCode (امتیاز 602)   1 2 11
+1 امتیاز
سلام.

اگه سایز آرایه مشخص باشه میتونید یک آرایه به عنوان آرایه ای از اندیس ها، به طور ثابت داشته باشید که اون رو به طور دستی مقدار بدید و با استفاده از اون هر ترتیبی رو میخاید پیاده کنید. یعنی به جای فرمول از یک نقشه ی از پیش تعیین شده ی ثابت استفاده کنید.
پاسخ داده شده دی 6, 1392 بوسیله ی محمد قدیانی (امتیاز 317)   1 9
نه متاسفانه سایز مشخص نیست و توسط کاربر تعیین میشه. برای همین redim کردیم. باید با استفاده از حلقه های for این مسئله حل بشه. ممنون میشم کمک کنید.
بسیار عالی بود ممنون http://www.nextmusic.ir
+1 امتیاز

این کد نصف ماتریس رو پر می کنه

برای اونی یکی قسمتشم باید حلقه ها رو بر عکس کنی

کد سی پلاس پلاس هستش تبدیلش به vb هم کاری نداره .

#include <iostream>

using namespace std;

int main()
{
    int num =1;
    int a[7][5];
    //meghdar avalie
    for(int i=0;i<7;i++)
        for(int j=0;j<5;j++)
           a[i][j]=-1;
    //
    for(int i=0;i<5;i++)
    {
        int k=i;
        for(int j=0;j<7;j++)
        {
            a[j][k]=num;
            num++;
            k--;
            if(k<0)
                break;

        }
    }
    for(int i=0;i<7;i++)
    {
        for(int j=0;j<5;j++)
          cout<<a[i][j]<<"  ";
        cout<<endl;
    }

    return 0;
}

 

پاسخ داده شده دی 6, 1392 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
ویرایش شده دی 6, 1392 بوسیله ی BlueBlade
ممنون میشم به vb6 تبدیلش کنید. متاسفانه سی پلاس پلاس را خوب بلد نیستم که خودم این کار را انجام بدم. ممنون.
کد تبدیل شده کد بالا:
Dim a(7, 5) As Integer
num = 1

For i = 0 To 7
    For j = 0 To 5
        a(i, j) = -1
    Next
Next
For i = 0 To 5
    k = i
    For j = 0 To 7
        a(j, k) = num
        num = num + 1
        k = k - 1
        If k < 0 Then Exit For
    Next
Next
For i = 0 To 7
    For j = 0 To 5
        MsgBox a(i, j)
    Next
Next

جالبه 35 خط کد شد 22 خط! بعد میگن ... (:
آخه من عادتم اینه هر { رو میزارم توی یک خط برشون دارم از 22 خط هم کمتر میشه
اون قسمت مقدار اولیه هم نیاز نیست
فقط برای اینکه بگم C++ کوچکتره:
#include <iostream>
int main() {
    int num = 1;
    int a[7][5];
    for(int i = 0;i < 5;i++)
        for(int j = 0, k = i;j < 7;j++) {
            a[j][k--] = num++;
            if(k < 0)
                break;
        }
    for(int i=0;i<7;i++)
        for(int j=0;j<5;j++)
          std::cout<<a[i][j]<<"  "<<std::endl;
}

در ضمن شما سر و ته تابع رو هم زدی.
ممنون کدی که واسه vb6 دادین عالی بود. فقط این کد یک مشکلی داره اونم اینه که در ادامه -1 چاپ می کنه! کدی هم که مربوط به -1 بود را حذف کردم اما شد 0! چرا کنیم که اصلا این کلا حذف بشه؟ ممنون.
من گفتم بهتون که این فقط نصفشو پر می کنه اون یکی نصفش رو باید از آخر بیای به اول همین مدلیه تقریبا .
میشه کد کامل را بدین؟ ممنون.
یا حتی 1 خط کمتر !
#include <iostream>
int main() {
    int a[7][5],num=1;
    for(int i = 0;i < 5;i++)
        for(int j = 0, k = i;j < 7;j++) {
            a[j][k--] = num++;
            if(k < 0)
                break;
        }
    for(int i=0;i<7;i++)
      for(int j=0;j<5;j++)
          std::cout<<a[i][j]<<"  "<<std::endl;
}
هر چه قدر سعی کردم خودم ویرایش اش کنم خطای Script out of range داد. اگه امکانش هست لطفا کد کامل به زبان vb6 را واسم بگذارید. ممنون.
+2 امتیاز

void GetNextIndex(
    const int Width,
    const int Height,
    const int i,
    const int j,
    bool * pToUpRight, // in-out (direction)
    int * pI,          // out
    int * pJ)          // out
{
    int I = i;         // out
    int J = j;         // out
    if (*pToUpRight)
    {
        I++;
        J--;
        if (J < 0)
        {
            J++;
            *pToUpRight = false;
        };
        if (I >= Width)
        {
            I--;
            *pToUpRight = false;
            J = j + 1;
        };
    }
    else // ToLeftDown
    {
        I--;
        J++;
        if (I < 0)
        {
            I++;
            *pToUpRight = true;
        };
        if (J >= Height)
        {
            J--;
            *pToUpRight = true;
            I = i + 1;
        };
    };
    *pI = I;
    *pJ = J;
}

int main()
{
    while (true)
    {
        int width, height;
        cin >> width;
        cin >> height;
        int * pm = (int*)malloc(width * height * sizeof(int));
        int k = 0;
        int i = 0;
        int j = 0;
        bool up_right = true;
        while (k < width * height)
        {
            k++;
            pm[j * width + i] = k;
            GetNextIndex(
                width,
                height,
                i,
                j,
                &up_right,
                &i,
                &j);
        };

        for (int j = 0; j < height; j++)
        {
            for (int i = 0; i < width; i++)
            {
                cout << pm[j * width + i] << "    ";
            };
            cout << endl;
        };
        cout << endl;

        cout << "-------------------------" << endl;
        free(pm);
    };

	return 0;
}

 

پاسخ داده شده دی 7, 1392 بوسیله ی محمد قدیانی (امتیاز 317)   1 9
ببخشید ولی این برای زبان C هست! اگه امکانش هست نسخه ی تبدیل شده به vb6 را قرار بدید. نسخه کامل. ممنون.
شرمنده که vb بلد نیستم. تبدیلش به عهده ی خودتون.
توضیحش اینه که یک تابع تعریف کردم که اندیس اخیر رو از شما میگیره (i و j ای که الان روش هستیم) بعد جهت اخیر حرکت رو هم میگیره (یا به سمت بالا و راست یا به سمت چپ و پایین) و اندیس بعدی رو به شما میده با جهت حرکت جدید. و اینجا یک if  لازمه. حالا مثلا برای حالت رو به بالا و راست، میایم به i یک واحد اافه میکنیم و از j یک واحد کم میکنیم. حالا اگر از اندیس مجاز بیرون نرفت که هیچ ولی اگر بیرون رفت، طبق if هایی که تو کد نوشتم i و j و تغییر میدیم. و همین طور برای حرکت رو به پایین و چپ. و نکته اینکه تابع باید به عنوان خروجی ، جهت حرکت فعلی رو که میگیره، با توجه به بیرون زدن i و j تو مراحل بالا باید جهت حرکت بعدی رو هم مشخص کنه. یعنی اگر به دیواره ها خورد جهت رو تغییر بده و برگردونه. کلا این تابع سه خروجی داره: i و j بعدی و جهت حرکت جدید.
ممنون. واقعا عالی بود.
...