Whatsup - לינוקס, תוכנה חופשית וקוד פתוח בעברית

תיכנות בלינוקס - מעבר במטריצה - אלכסון

elcuco - 20/06/2017 - 19:28
נושא ההודעה: מעבר במטריצה - אלכסון
אני צריך לעשות ביקור במטריצה, בדרך כלל הקוד שלי נראה ככה:
קוד:

for (int x=0; x<100; x++) {
  for( int y=0; y<100; y++) {
     /// ...
  }
}


וזה נותן לי ביקור כזה:
קוד:

[0,0] [1,0], [2,0]...[99,0], [0,1], [1,2]....

וכו.

אני מחפש קוד שיעשה ביקור בצורה כזאת:
קוד:

[0,0] [0,1], [1,0], [0,2], [1,1], [3,0], [4,0], [3,2], [2,3]


מין זיג זג כזה... תודה!
Anonymous - 20/06/2017 - 20:05
נושא ההודעה:
אם הבנתי אותך נכון (נראה לי שהדוגמה של ה"ביקור" שנתת לא מתאימה לקוד שכתבת), אז אתה צריך משהו כזה, בערך:


קוד:

for (int sum=0; sum<100; sum++)
{
    for (int x=0; x<=sum; x++)
    {
         do_something(x, sum - x);
    }
}


אולי תצטרך להחליף את הסדר בקריאה ל-do_something אבל נסה וראה.
Anonymous - 20/06/2017 - 20:16
נושא ההודעה:
מה שכתבתי יעבור על האלכסונים אבל באותו כיוון – אם התכוונת שכל מעבר יהיה בכיוון שונה, נראה לי שבתוך הלולאה הפנימית תבדוק אם sum זוגי או לא, ותחליף את סדר הפרמטרים בקריאה ל-do_something לפי הזוגיות.

מכאן בטח תסתדר :-)
elcuco - 23/06/2017 - 11:52
נושא ההודעה:
Anonymous :
מה שכתבתי יעבור על האלכסונים אבל באותו כיוון – אם התכוונת שכל מעבר יהיה בכיוון שונה, נראה לי שבתוך הלולאה הפנימית תבדוק אם sum זוגי או לא, ותחליף את סדר הפרמטרים בקריאה ל-do_something לפי הזוגיות.

מכאן בטח תסתדר Smile

בהנחה שכתבתי טוב את מה שהצעת - הינה הקוד המלא:

קוד:

#include "stdafx.h"
#include <functional>
#include <iostream>

#define MAX_X 8
#define MAX_Y 8

void fillMatrix(int matrix[MAX_Y][MAX_X]);
void visitMatrix(int matrix[MAX_Y][MAX_X], std::function<void(int y, int x, int value)> visitor);
void visitMatrix2(int matrix[MAX_Y][MAX_X], std::function<void (int y, int x, int value)> visitor);

int main()
{
   int theMatrix[MAX_Y][MAX_X];
   auto visitor = [](int y, int x, int value) {
      printf("%02d:%02d=%02d%s", y, x, value, (x == MAX_X - 1) ? "\n" : "  ");
   };
   fillMatrix(theMatrix);
   visitMatrix(theMatrix, visitor);
   printf("-------------------------\n");
   visitMatrix2(theMatrix, visitor);

    return EXIT_SUCCESS;
}

void fillMatrix(int matrix[MAX_Y][MAX_X]) {
   int value = 0;
   for (int y = 0; y < MAX_Y; y++) {
      for (int x = 0; x < MAX_X; x++) {
         matrix[y][x] = value;
         value++;
      }
   }
}

void visitMatrix(int matrix[MAX_Y][MAX_X], std::function<void(int y, int x, int value)> visitor) {
   for (int y = 0; y < MAX_Y; y++) {
      for (int x = 0; x < MAX_X; x++) {
         visitor(y, x, matrix[y][x]);
      }
   }
}

void visitMatrix2(int matrix[MAX_Y][MAX_X], std::function<void(int y, int x, int value)> visitor) {
   for (int sum = 0; sum < MAX_Y; sum++) {
      for (int x = 0; x <= sum; x++) {
         visitor(x, sum - x, matrix[sum][sum - x]);
      }
   }
}


והינה הפלט:
קוד:

00:00=00  00:01=01  00:02=02  00:03=03  00:04=04  00:05=05  00:06=06  00:07=07
01:00=08  01:01=09  01:02=10  01:03=11  01:04=12  01:05=13  01:06=14  01:07=15
02:00=16  02:01=17  02:02=18  02:03=19  02:04=20  02:05=21  02:06=22  02:07=23
03:00=24  03:01=25  03:02=26  03:03=27  03:04=28  03:05=29  03:06=30  03:07=31
04:00=32  04:01=33  04:02=34  04:03=35  04:04=36  04:05=37  04:06=38  04:07=39
05:00=40  05:01=41  05:02=42  05:03=43  05:04=44  05:05=45  05:06=46  05:07=47
06:00=48  06:01=49  06:02=50  06:03=51  06:04=52  06:05=53  06:06=54  06:07=55
07:00=56  07:01=57  07:02=58  07:03=59  07:04=60  07:05=61  07:06=62  07:07=63
-------------------------
00:00=00  00:01=09  01:00=08  00:02=18  01:01=17  02:00=16  00:03=27  01:02=26
02:01=25  03:00=24  00:04=36  01:03=35  02:02=34  03:01=33  04:00=32  00:05=45
01:04=44  02:03=43  03:02=42  04:01=41  05:00=40  00:06=54  01:05=53  02:04=52
03:03=51  04:02=50  05:01=49  06:00=48  00:07=63
01:06=62  02:05=61  03:04=60  04:03=59  05:02=58  06:01=57  07:00=56


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

הערה לעצמי - איכס... לעבוד עם VisualStudio ביישומי מסוף זה ממש לא כיף... גם העורך נלחם איתי טיפה... או להיפך.
Anonymous - 23/06/2017 - 12:13
נושא ההודעה:
אולי ה async של js עם ה non blocking one threading יעזור לך לעקם את האלכסונים
Anonymous - 23/06/2017 - 14:50
נושא ההודעה:
אם הבנתי נכון נדמה לי שזה מה שאתה רוצה:

קוד:

void visitMatrix(int matrix[MAX_Y][MAX_X], std:: function < void(int y, int x, int value) > visitor) {

  int x = 0;
  int y = 0;
  int direction = 1;

  do {
    visitor(y, x, matrix[y][x]);
    y = y + direction;
    x = x - direction;
    if (x < 0) {
      x = 0;
      direction = -1 * direction;
    }
    if (y < 0) {
      y = 0;
      direction = -1 * direction;
    }
    if (y > MAX_Y) {
      y = MAX_Y;
      direction = -1 * direction;
    }
    if (x > MAX_X) {
      x = MAX_X;
      direction = -1 * direction;
    }

  } while (x != MAX_X && y != MAX_Y);
}

Anonymous - 23/06/2017 - 16:01
נושא ההודעה:
קבל תיקון הקודם עבר רק על החצי הראשון של המטריצה
קוד:

void visitMatrix(int matrix[MAX_Y][MAX_X], std::function<void(int y, int x, int value)> visitor) {

   int x = 0;
   int y = 0;
   int direction = 1;

   do{
   visitor(y, x, matrix[y][x]);
   y = y + direction;
        x = x - direction;
   if(y >= MAX_Y){
         y = MAX_Y - 1;
    x = x + 2;
         direction = -1 * direction;
        }
   if(x >= MAX_X){
         x = MAX_X - 1;
    y = y + 2;
         direction = -1 * direction;
        }   
   if(x < 0){
    x = 0;   
    direction = -1 * direction;
        }
   if(y < 0){
    y = 0;   
    direction = -1 * direction;
        }
   } while (x < MAX_X && y < MAX_Y)
}

Anonymous - 23/06/2017 - 16:23
נושא ההודעה:
טוב, אז הנה קוד מסודר שמבוסס על ההצעה הראשונית שלי:
קוד:


#include <stdio.h>

#define COLS 3
#define ROWS 5

void visit(int col, int row)
{
  printf("(%d, %d) ", col, row);
}
 
int main()
{

  int max_diagonal = COLS + ROWS - 2;
  for (int diagonal = 0; diagonal <= max_diagonal; diagonal++)
    {
      int max_col = diagonal > COLS - 1 ? COLS - 1 : diagonal;

      /* just for testing */
      printf("\ndiagonal: %4d >>>  ", diagonal);
     
      for (int col = 0; col <= max_col; col++)
   {
     /* reverse visiting order on even pass */
     int actual_col = diagonal % 2 ? col : max_col - col;
     int row = diagonal - actual_col;
     /* stay within limits */
     if (row >= ROWS)
         continue;

     visit(actual_col, row);
   }
    }
}


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

האינדקסים הם zero-based, כלומר נעים מאפס ועד למספר השורות/עמודות פחות 1.
Anonymous - 23/06/2017 - 23:28
נושא ההודעה:
מתקן את עצמי – הוצאתי את בדיקת הגבולות מחוץ ללולאה הפנימית, יותר יעיל ופשוט, וכמה שינויים נוספים לפישוט הקוד.

קוד:

#include <stdio.h>

#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))

void visit(int col, int row)
{
  printf("(%d, %d) ", col, row);
}

/* scan matrix that have 'cols' columns and 'rows' rows,
along its diagonals */
void scan_diagonally(int cols, int rows)
{
  int max_diagonal = cols + rows - 2;
  for (int diagonal = 0; diagonal <= max_diagonal; diagonal++)
    {
      /* restrict column limit to be inside the matrix */
      int max_col = MIN(diagonal, cols -1);
      int min_col = MAX(diagonal - rows + 1, 0);
      /* need to know so we can reverse pass order */
      int is_odd_pass = diagonal % 2;

      /* just for testing */
      printf("\ndiagonal %4d  >>> ", diagonal);
     
      for (int col = min_col; col <= max_col; col++)
   {
     /* reverse visiting order on even pass - on even pas, start
        from the end and go backward */
     int actual_col = is_odd_pass ? col : max_col + min_col - col;

     /* row = diagonal - col */
     visit(actual_col, diagonal - actual_col);
   }
    }
}

int main()
{
  scan_diagonally(5, 7);
  return 0;
}

Anonymous - 25/06/2017 - 13:58
נושא ההודעה: שאלה ליניארית
מזמן למדתי קצת על מטריצות ומעולם לא השתמשתי וחשבתי שזו היתה סתם התעללות בחסר ישע Sad

אשמח לדעת מה השימוש שלכם במטריצות? אולי גם אני אתחיל להשתמש...
elcuco - 25/06/2017 - 20:05
נושא ההודעה: Re: שאלה ליניארית
Anonymous :
מזמן למדתי קצת על מטריצות ומעולם לא השתמשתי וחשבתי שזו היתה סתם התעללות בחסר ישע Sad

אשמח לדעת מה השימוש שלכם במטריצות? אולי גם אני אתחיל להשתמש...


שולה המוקשים - דוגמה
עריכה:
- כל המידע שנמשך מבסיס נתונים רלציוני הוא טבלה - מטריצה. ועליו מפעילים מכפלות ווקטוריות וקארטזיות.
- כל המידע שמתקבל במפה הוא עבר הטלה - מכדור תלת מימדי אל מפה דו מימדית, וזה נעשה בעזרת מכפלות מטריצות.
- הצפנות מבוססות block cypher שהן בעצם הפיכת הווקטור החד מימדי, אל מטריצה רבועית ואז מכפלה שלה עם מטריצת ההצפנה שלך (לפני או אחרי עירבול).
borsood - 26/06/2017 - 07:22
נושא ההודעה: זה C או C++?
הקוד מספיק מודרני כדי להתשמש ב std::function אבל לא ב std::vector או במינימום ב std::array ?
שימוש בלולאות מודרניות היה חוסך אתת out of bounds ועוד כמה צרות.
elcuco - 26/06/2017 - 09:55
נושא ההודעה: Re: זה C או C++?
borsood :
הקוד מספיק מודרני כדי להתשמש ב std::function אבל לא ב std::vector או במינימום ב std::array ?
שימוש בלולאות מודרניות היה חוסך אתת out of bounds ועוד כמה צרות.


יאללה קדימה - תוכיח Smile
Anonymous - 26/06/2017 - 13:14
נושא ההודעה:
ציטוט:
שולה המוקשים - דוגמה
עריכה:
- כל המידע שנמשך מבסיס נתונים רלציוני הוא טבלה - מטריצה. ועליו מפעילים מכפלות ווקטוריות וקארטזיות.
- כל המידע שמתקבל במפה הוא עבר הטלה - מכדור תלת מימדי אל מפה דו מימדית, וזה נעשה בעזרת מכפלות מטריצות.
- הצפנות מבוססות block cypher שהן בעצם הפיכת הווקטור החד מימדי, אל מטריצה רבועית ואז מכפלה שלה עם מטריצת ההצפנה שלך (לפני או אחרי עירבול).

תודה על ההסבר - מענין מאוד ומעורר מחשבות רב מימדיות!
קצת משחרר לדעת שההתעללות בקורס אלגברה לינארית לא היתה לשווא Smile
כל הזמנים הם GMT + 2 שעות