עבור לתוכן

הדפסת שבלול בC

Featured Replies

פורסם

שלום,

אני צריך קוד לשאלה הבאה. אין לי כיוון אפילו, אז תודה לכל מי שיוכל לעזור:

כתוב תכנית המקבלת מספר n ומדפיסה "שבלול" בגודל n * n

לפי דוגמה הבאה :

עבור 5 = n הפלט :

13 14 15 16 1

12 23 24 17 2

11 22 25 18 3

10 21 20 19 4

9 8 7 6 5

תודה לכל העוזרים.

פורסם

סליחה שאני מתפרץ.

אני מנסה כרגע לבנות תוכנית כזו אך אני לא יודע כיצד ניתן להקצות דינמית מערך דו מימדי ב-C או ++C.

מישהו יכול לעזור?

בתודה מראש

פורסם

טוב קודם אענה לאור, ואחר כך אחשוב על הפתרון של השבלול.

עבור הקצאה בC - רשמתי לפני כמה תראדים איך עושים את זה(תחפש פויינטרים או מצביעים).

בC++ -


p=new type[size];
delete [] p;

לא צריך ספריות מיוחדות.

אם size = 1 אתה יכול להוריד את מהשורה הראשונה, ואת הסוגריים [] מהשורה השנייה.

עריכה: צריכה להיות כאן פונ תפר כלשהי עבור שורה גדול מעמודה או ההיפך. משהו עם 5*n-8. אני אמשיך לבדוק.

עריכה 2: הצלחתי לכסות את השורה והעמודה הראשונה:

j, 1 => j

1, i => 5*n-8-i+2

פורסם

אופיר,

הקצאה דינמית אני יודע לעשות. השאלה היא איך אני עושה את זה עבור מערך דו מימדי. ???

פורסם

כישורי ה c שלי די חלודים אבל הרעיון די פשוט והוא עובד.

הגדרתי מערך של מצביעים לפונקציות, המכיל 4 פונקציות: אחת עבור כל כיוון התקדמות (ימינה, שמאלה, למעלה ולמטה). התוכנית הראשית מקצה דינמית מערך ומעבירה אותו לפונקציה שמכניסה אליו את המספרים.

תחילה "מתקדמים" מהפינה השמאלית העליונה למטה, לאחר מכן ימינה ואז שמאלה. משם כל שתי "התקדמויות" מפחיתים את מספר ההתקדמויות באחד.

#include <stdio.h>

typedef void (*advanceDirFunc)(int*, int, int, int *, int *);

void Advance(int *arr, int n, int inc, int steps, int row, int col)
{
int i;
int *ptr = arr+row*n+col;
int val = *ptr;
ptr += inc;

for(i=1;i<steps; i++, ptr+=inc)
*ptr = ++val;
}

void AdvanceDown(int *arr, int n, int steps, int *row, int *col)
{
Advance(arr, n, n, steps, *row, *col);
(*row) += steps-1;
}

void AdvanceRight(int *arr, int n, int steps, int *row, int *col)
{
Advance(arr, n, 1, steps, *row, *col);
(*col) += steps-1;
}
void AdvanceUp(int *arr, int n, int steps, int *row, int *col)
{
Advance(arr, n, -n, steps, *row, *col);
(*row) -= steps-1;
}

void AdvanceLeft(int *arr, int n, int steps, int *row, int *col)
{
Advance(arr, n, -1, steps, *row, *col);
(*col) -= steps-1;
}

void FillArray(int *arr, int n)
{
advanceDirFunc funcDirs[4] = {&AdvanceDown, &AdvanceRight, &AdvanceUp, &AdvanceLeft};

int i = 3;
int col=0, row=0;
int steps = n-1;
int temp;

*arr = 1;

AdvanceDown(arr, n, n, &row , &col);
AdvanceRight(arr, n, n, &row , &col);
AdvanceUp(arr, n, n, &row , &col);

while(steps>1)
{
(*funcDirs[i++])(arr, n, steps, &row , &col);
if(i==4) i=0;
(*funcDirs[i++])(arr, n, steps, &row , &col);

steps--;
}
}

void PrintArray(int *arr, int n)
{
int *ptr = arr;
int i, j;

for(i=0;i<n; i++)
{
for(j=0; j<n; j++, ptr++)
printf("%2d ",*ptr);
printf("\n");
}
}

int main(void)
{
int n;
int *arr = NULL;

scanf("%d",&n);
arr = (int*)calloc(n*n,sizeof(int));
if(!arr)
{
printf("Error allocating memory.");
return -1;
}

FillArray(arr, n);
PrintArray(arr, n);

free(arr);
return 0;
}

פורסם

קובי, לא הספקתי לעבור על הפתרון שלך, אבל לפי האורך ניתן להבחין שעשית עבודה לא רעה.

אני עדיין מנסה למצוא מישהו שיסביר לי כיצד עושים הקצאה דינמית של מערכים דו מימדיים כי בינתיים אני פשוט נאלץ להגדיר את גודל הריבוע ב-define בשם LONG אבל חוץ מזה התוכנית עובדת מצוין.

#define LONG 9

#include <iostream.h>

int main(){
int matrix[LONG][LONG];
int i,j,k;
int size=LONG;
int num=1;

for(i=j=k=0;k<size/2;k++,i++,j++){
for(;i<size-k;i++,num++)
matrix[i][j] = num;

for(i--,j=1+k;j<size-k;j++,num++)
matrix[i][j] = num;

for(i--,j--;i>=k;i--,num++)
matrix[i][j] = num;

for(i++,j--;j>k;j--,num++)
matrix[i][j] = num;
}

if(size%2){
int center = size/2+0.5;
matrix[center][center] = num;
}

for(i=0;i<size;i++){
for(j=0;j<size;j++)
cout<<matrix[i][j]<<" ";

cout<<endl;
}

return 0;
}

פורסם

מה שאני עשיתי (כי באותו רגע לא זכרתי את כל הדרכים לעשות את זה) היה להגדיר מצביע רגיל בגודל של המערך הדו מימדי (n*n) וניגשתי לכל תא לפי המיקום שלו במערך הדו מימדי (בפונקציה advane):

int *ptr = arr+row*n+col;

כאשר arr הוא המצביע לתחילת המערך, row הוא מס' השורה בה ממוקם התא ו-col הוא מס' הטור של התא (n הוא מספר התאים בשורה).

מחיפוש קצר בגוגל מצאתי את הדוגמה הבאה שאולי תעזור לך:

http://www.geocities.com/spur4444/prog/multidimensional.html

פורסם

תודה רבה, הדוגמא עזרה לי מאוד. לאחר השינוי:

#include <iostream.h>

int main(){
int** matrix;
int i,j,k;
int size;
int num=1;

cout<<"Please enter long of rectangle."<<endl;
cin>>size;
cout<<endl;

matrix = new int* [size];

for(i=0;i<size;i++)
matrix[i] = new int[size];

for(i=j=k=0;k<size/2;k++,i++,j++){
for(;i<size-k;i++,num++)
matrix[i][j] = num;

for(i--,j=1+k;j<size-k;j++,num++)
matrix[i][j] = num;

for(i--,j--;i>=k;i--,num++)
matrix[i][j] = num;

for(i++,j--;j>k;j--,num++)
matrix[i][j] = num;
}

if(size%2){
int center = size/2+0.5;
matrix[center][center] = num;
}

for(i=0;i<size;i++){
for(j=0;j<size;j++)
cout<<matrix[i][j]<<" ";

cout<<endl;
}

for(i=0;i<size;i++)
delete[] matrix[i];

delete[] matrix;

return 0;
}

עריכה: הוספתי כעת גם שחרור של הזכרון.

פורסם

למה אתם עובדים עם מערכים בכלל?

ביקשו ממנו רק להדפיס את השבלול...

פורסם

המספרים מאורגנים בריבוע לכן נוח להשתמש במערך דו מימדי (או לפחות בגישה בצורה של מערך ד מימדי כמו שעשיתי בתוכנית שלי).

אי אפשר סתם להדפיס את המספרים שורה אחרי שורה (וגם אם כן זה סתם מסובך) כי הרצף של המספרים עובר בכל הריבוע, לכן צריך לחשב את המספרים לפי הרצף של השבלול ולא שורה אחרי שורה.

עריכה: orlupo שכחת לשחרר את הזיכרון אחריך. אתה צריך לשחרר כל מערך בנפרד ואז את המערך ה"ראשי" בעזרת האופרטור delete[].


for (i = 0; i < size; ++i)
delete[] matrix[i];

delete[] matrix;

פורסם

בטח יש איזושהי נוסחא... רק שאני לא עולה עליה....

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים