עבור לתוכן

עזרה כתבתי פונקציה למיון מטריצה והיא פועלת לי חלקית(שפת C)

Featured Replies

פורסם

כתבתי את הפונקציה הבאה שמקבלת שתי מטריצות זהו אחת של מספרים ואחת שבכל תא שלה יש את סכום הספרות בתא המקביל לו במטריצת המספרים

הפונצקיה אמורה לסדר את מטריצת המספרים בסדר עולה לפי סכום האיברים שבאותה שורה.

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

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

int v,i,j,S=1,sum1=0,sum2=0,temp;

for(v=1;v<N;v++)

{

for(i=0;i<N-S;i++)

{

sum1=0;

sum2=0;

for(j=0;j<N;j++)

sum1+=mat2[j];

for(j=0;j<N;j++)

sum2+=mat2[i+1][j];

if(sum2>sum1)

for(j=0;j<N;j++)

{

temp=mat[j];

mat[j]=mat[i+1][j];

mat[i+1][j]=temp;

}

}

S++;

}

פורסם

דבר ראשון לא כ"כ הבנתי מה התוכנית אמורה לעשות, אתה יכול לתת גודמא לתוצאה נכונה?

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

פורסם
  • מחבר

הנה דוגמא....

יש מטריצה בגודל 3X3

14 15 16

11 12 13

17 18 19

ועוד מטריצה שמכילה את סכום של כל תא:

5 6 7

2 3 4

8 9 10

הפונקציה מקבלת את שתי המטריצות ומסדרת את סדר השורות לפי סכום האיברים בשורה

ככה שאמור להתקבל בסוף המטריצה הזאת:

17 18 19

14 15 16

11 12 13


int v,i,j,S=1,sum1=0,sum2=0,temp;
for(v=1;v<N;v++)
{
for(i=0;i<N-S;i++)
{
sum1=0;
sum2=0;
for(j=0;j<N;j++)
sum1+=mat2[i][j];
for(j=0;j<N;j++)
sum2+=mat2[i+1][j];
if(sum2>sum1)
for(j=0;j<N;j++)
{
temp=mat[i][j];
mat[i][j]=mat[i+1][j];
mat[i+1][j]=temp;
}
}
S++;
}

פורסם

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

פורסם
  • מחבר

שאלה 2

.5X5 המגדירה מטריצה של מספרים שלמים בגודל C כתוב תוכנית בשפת

א. התוכנית תקלוט מספרים שלמים בין 1-1000 למטריצה ותוודא את תקינות הקלט.

בכל פעם שמוכנס מספר שגוי תבקש מספר חדש.

ב. התוכנית תחשב ותדפיס מטריצה חדשה, אשר כל אחד מאיבריה שווה לסכום

הספרות של האיבר המתאים לו במטריצה המקורית.

ג. התוכנית תחשב ותדפיס מטריצה חדשה. במטריצה החדשה מסודרות כל שורות

המטריצה המקורית, ממוינות לפי סכום איברי השורה. כלומר, שורה מספר 1 תהיה

השורה בעלת סכום האיברים הגדול ביותר במטריצה המקורית, שורה מספר 2 תהיה

השורה שסכום איבריה קטן יותר והשורה האחרונה תהיה זו שסכום איבריה הקטן

ביותר.

זה התרגיל שקיבלתי, הפונקציה שבה הסתבכתי אמורה לממש את סעיף ג'...

פורסם

אוקי עכשיו זה ברור.

* בהנחה שאת 1+2 פתרת נכון *

הלולאה החיצונית צריכה להיות

for (v=0 ; v<N ; v++)

הלולאה הפנימית צריכה להיות

for (i=0 ; i<N-v-1 ; i++)

פחות v כי ב-bubble sort בכל איטרציה בלולאה הפנימית יורדים באחד. פחות 1 כי אתה משווה עם השורה הבאה ובלי זה אתה תצא מגבולות המטריצה.

אופטימיזציה:

את ההחלפה תבצע כך


<T> temp[N];
memcpy(temp,mat[i],sizeof(T)*N);
memcpy(mat[i],mat[i+1],sizeof(T)*N);
memcpy(mat[i+1],temp,sizeof(T)*N);

פורסם
  • מחבר

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

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

נגיד למערך 1 1 1

2 2 2

3 3 3

הוא יהפוך את הסדר כמו שצריך

אבל למערך 1 1 1

3 3 3

2 2 2

הוא פשוט לא יעשה כלום =\

פורסם

תעתיק לכאן את הקוד כמו שהוא עכשיו.

פורסם
  • מחבר


#include <stdio.h>
#include <conio.h>
#define N 3
void kelet(int mat[][N]);
int findsum(int a);
void printmat(int mat[][N]);
void ordermat(int mat[][N],int mat2[][N]);


void main()
{
int mat[N][N],mat2[N][N],i,j;
kelet(mat);
for(i=0;i<N;i++)
for(j=0;j<N;j++)
mat2[i][j]=findsum(mat[i][j]);
printmat(mat2);
ordermat(mat,mat2);
getch();

}
void ordermat(int mat[][N],int mat2[][N])
{
int v,i,j,S=1,sum1=0,sum2=0,temp;
for (v=0 ; v<N ; v++)
{
for (i=0 ; i<N-v-1 ; i++)
{
sum1=0;
sum2=0;
for(j=0;j<N;j++)
sum1+=mat2[i][j];
for(j=0;j<N;j++)
sum2+=mat2[i+1][j];
if(sum2>sum1)
for(j=0;j<N;j++)
{
temp=mat[i][j];
mat[i][j]=mat[i+1][j];
mat[i+1][j]=temp;
}
}
}
printmat(mat);
}
void printmat(int mat[][N])
{
int i,j;
for(i=0;i<N;i++){
for(j=0;j<N;j++)
printf("%4d",mat[i][j]);
printf("\n");}
printf("\n");
}

int findsum(int a)
{
int sum=0;
while(a>0)
{
sum+=a%10;
a/=10;
}
return sum;
}
void kelet(int mat[][N])
{
int i,j;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{
printf("enter a num to matrix int line %d row %d\n",i,j);
scanf("%d",&mat[i][j]);
if(!(mat[i][j]>0&&mat[i][j]<=1000))
{
printf("erorr enter another number!\n");
j--;
}
}
printf("mat comlete!\n");
}

פורסם

הבנתי למה זה לא עובד. אם היית מבצע step by step גם אתה היית מבין.

אתה בודק לפי השורות ב-mat2 אבל ברגע שאתה משנה את סדר השורות ב-mat1 אין כבר התאמה ביניהן. אתה צריך להחליף את אותן שורות גם ב-mat2.

פורסם
  • מחבר

תודה רבה רבה רבה אחשליי!!!!

כבר התחרפנתי ולא הבנתי איפה טעיתי...

פורסם

אגב, המיון שאתה עושה הוא לא ממש יעיל. כל פעם שאתה מחליף בין שתי שורות אתה עושה הרבה פעולות מיותרות. לדוגמה, אתה מחשב את הסכומים בכל שורה שוב ושוב, וכשאתה מחליף בין שתי שורות אתה צריך להעתיק את כל השורה, שזו פעולה "כבדה". למעשה, הסיבוכיות של המיון שלך היא (O(n^3 כשמיון בועות רגיל הוא (O(n^2.

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

/* initialize indices and sums */
int indices[N];
int sums[N];
for (i = 0 ; i < N ; i++) {
indices[i] = i;
sums[i] = 0;
for (j = 0 ; j < N ; j++) {
sums[i] += mat[i][j];
}
}

/* sort indices according to sums */
for (j = 0 ; j < N ; j++) {
for (i = 0 ; i < N-j-1 ; i++) {
if (sums[indices[i]] < sums[indices[i+1]]) {
temp = indices[i];
indices[i] = indices[i+1];
indices[i+1] = temp;
}
}
}

/* re-order the matrix according to indices (copy to a temporary matrix first) */
int tempmat[N][N];
memcpy(tempmat, mat, sizeof(mat));
for (i = 0 ; i < N ; i++) {
memcpy(mat[i], tempmat[indices[i]], sizeof(int)*N);
}

אני לא סגור על זה שה-memcpy יעבוד בדיוק כמצופה, אבל אני מקווה שהעקרון מובן.

פורסם

אם הולכים על יעילות אז במקום להשתמש במטריצה עדיף להשתמש במערך פויינטרים לוקטורים ואז פשוט להחליף את הפויינטרים במקום להחליף את כל השורה. כלומר:


int** createTable(int n)
{
int** ptr = null;
ptr = new int*[n];
if (ptr!=null)
{
for (int i=0; i < n ; i++)
{
ptr[n] = new int[n];
if ptr[n]==null
{
for(;i>=0;i--)
delete[] ptr[i];
delete[] ptr;
return null;
}
memset(ptr[n],0,n*sizeof(int));
}
return ptr;
}

void setValue(int** ptr, int i, int j,int val)
{
(ptr[i])[j]=val;
}


int getValue(int** ptr, int i, int j,int val)
{
return (ptr[i])[j];
}

void swapRows(int** ptr, int r1,int r2)
{
void* tempPtr = ptr[r1];
ptr[r1]=ptr[r2];
ptr[r2]=tempPtr;
}

אין לי סביבת פיתוח על המחשב אז אני לא יכול לבדוק אם זה בכלל מתקמפל אבל זה אמור לעבוד. אגב זה קוד ++C אבל אפשר לשנות אותו שיעבוד ב-C. רק צריך להחליף new ו-delete ב-malloc ו-free בהתאמה.

ארכיון

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

דיונים חדשים