Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Όποιος μπορεί ας προτείνει ένα πιο κομψό τρόπο να γραφτεί το παρακάτω foor-loop.

for (int i = 0; i < MAX_NO_TRIANGLES; i++) {
   if (Triangles[i].mA == v2 || Triangles[i].mB == v2 || Triangles[i].mC == v2) {
       if (Triangles[i].mA == v3 || Triangles[i].mB == v3 || Triangles[i].mC == v3) {
           if (Triangles[i].mA == v1 || Triangles[i].mB == v1 || Triangles[i].mC == v1) {
           }
           else {
              adjTriangle = i;
              i = MAX_NO_TRIANGLES;
           }
       }
   }
 
   if (i == MAX_NO_TRIANGLES-1) {
      if (Triangles[i].mA == 0 && Triangles[i].mB == 0 && Triangles[i].mC == 0)
         return 1;
   }
}
Δημοσ.

fun mode on

 

Αυτό πάει στην αρχή του πρώτου post. :P

 

Φαντάζομαι η αρχική ερώτηση δεν είναι σοβαρή...

  • Moderators
Δημοσ.

Πώς θα σου φαινόταν κάτι τέτοιο;

 

 

int A = (Triangles[i].mA == v2 || Triangles[i].mB == v2 || Triangles[i].mC == v2);
int B = (Triangles[i].mA == v3 || Triangles[i].mB == v3 || Triangles[i].mC == v3);
int C = (Triangles[i].mA == v1 || Triangles[i].mB == v1 || Triangles[i].mC == v1);
 
if (A && 
{
    if (C)
    {    }
    else
    {
        adjTriangle = i;
        i = MAX_NO_TRIANGLES;
    }
}
 
  • Like 1
Δημοσ.

Λογικά δεν υπάρχει κάποιος τρόπος να το κάνεις πιο κομψό κόβοντας κάπως της if, μιας και το πρόβλημα είναι της μορφής

 

(A | B | C) & (D | E | F) & !(G & H & I)

 

Κάποιες αλλαγές που θα μπορούσαν να γίνουν θα ήταν να τσεκάρεις πριν την for για το αν είναι μηδενικά το τελευταίο row του πίνακα και να περνάς τα v1/v2/v3 σαν array (έστω vArray[3] = { v1, v2, v3 }).

 

π.χ.

int i = MAX_NO_TRIANGLES - 1;
int j;

if (Triangles[i].mA == 0 && Triangles[i].mB == 0 && Triangles[i].mC == 0)
    return 1;

for (; i >= 0; --i) {
    for (j = 2; j >= 0; --j) {
        if (Triangles[i].mA != vArray[j] && Triangles[i].mB != vArray[j] && Triangles[i].mC != vArray[j])
            break;            
    }
    
    if (j == 0) {
        adjTriangle = i;
        break;
    }
}

Η εσωτερική for στην ουσία κάνει τους ελέγχους που έκανες με τις nested if πριν.

 

- Αν το j έχει τιμή 2 όταν βγει από την for, σημαίνει πως δεν βρέθηκε τιμή στα Triangles.mA/mB/mC που να ταιριάζει με το v3

- Αν το j έχει τιμή 1 όταν βγει από την for, σημαίνει πως δεν βρέθηκε τιμή στα Triangles.mA/mB/mC που να ταιριάζει με το v2

- Αν το j έχει τιμή 0 όταν βγει από την for, σημαίνει πως δεν βρέθηκε τιμή στα Triangles.mA/mB/mC που να ταιριάζει με το v1 (περίπτωση else)

- Αν το j έχει τιμή -1 όταν βγει από την for, σημαίνει πως βρέθηκε τιμή στα Triangles.mA/mB/mC που να ταιριάζει με το v1 (περίπτωση if με κενό κώδικα).

 

Τα v3/v2 τα τσεκάρεις ανάποδα με το παραπάνω, αλλά λογικά δεν σε επηρεάζει αφου τα χρειάζεσαι και τα δύο πριν φτάσεις στον τρίτο έλεγχο. Στην χειρότερη απλά βάζεις ανάποδα τις τιμές στις θέσεις 1/2 του πίνακα που έχει τα values.

 

Είναι αργά και μπορεί να έχω μπερδέψει τις αντιστροφές == / != και && / ||, συγνώμη εκ των προτέρων.

 

Προσωπικά, σε σχέση με το αρχικό, αυτό εδώ δείχνει πιο arcane, αλλά είναι το μόνο ενδιαφέρον που μπορώ να σκεφτώ.

Δημοσ.

Γιατί;

 

Α όντως ρωτάς; Σόρρυ. Απ' την κούραση ίσως μου φάνηκε κουλή εξ' αρχής.

 

Το πρόβλημα σου λίγο διαφορετικά διατυπωμένο είναι το εξής:

  • Για να μπεις στο 3ο if αυτό που σε ενδιαφέρει είναι: Κάθε στοιχείo v να αντοιστοιχίζεται σε ακριβώς ένα στοιχείο m.
  • Για να μπεις στο else κάτω από το 3o if σε ενδιαφέρει τα v2 και v3 να έχουν αντιστοιχηθεί κάπου, αλλά όχι το v1.

Δεν ξέρω τι γλώσσα χρησιμοποιείς. Αν είναι C, αλλά έχεις έχεις έτοιμες δυναμικές λίστες, απλά δημιούργησε δύο λίστες η μία με τα v1, v2, v3 και η άλλη με τα mA, mB, mC. Στη συνέχεια κάνεις μέχρι 9 το πολύ επαναλήψεις ή μέχρι οι πίνακες να έχουν αδειάσει, με δεδομένο ότι σε κάθε match αφαιρείς τα v και m που έγιναν match. Αυτό μπορεί να γίνει με ένα loop και χρησιμοποιώντας για jump είτε -3 και mod 3 για να παίρνεις τα στοιχεία, είτε σε κάθε match βάζοντας τον δείκτη σου στο vTableSize*mTableSize (προφανώς ξεκινώντας αρχικά από το 9 = vTableSize*mTableSize και κατεβαίνοντας).

 

Το ίδιο πρόβλημα μπορεί να λυθεί και με δέντρα και πάει λέγοντας...

 

Φυσικά δεν ξέρω κατά πόσο αξίζει να κάνεις κάτι τέτοιο. Αυτό εσύ το κρίνεις, ειδικά αν πρόκειται για pure C. Αν θες παραπάνω εξήγηση ή κώδικα, πες μου να το αναλύσω. Όλα αυτά με δεδομένου ότι κατάλαβα σωστά τι προσπαθείς να κάνεις.

Δημοσ.

Παιδιά ευχαριστώ για τς απαντήσεις! Και εγώ είμαι λίγο κουρασμένος εξού και ότι δεν διευκρίνισα επαρκώς. 

Λοιπόν πολύ πολύ συνοπτικά είναι C++ και πρόκειται για high level synthesis σε RTL κώδικα. Bottom line είναι ότι υπάρχουν περιορισμοί διάφοροι, όπως πχ, ότι τα loops δεν μπορεί να είναι unknown (δυναμικές λίστες που αναφέρθηκαν κλπ τα ξεχνάμε).

Με ενδιαφέρει λοιπόν ένα όσο το δυνατόν περισσότερο flatten implementation καθότι αυτό καθορίζει το resulting hardware architecture structure σχετικά με το latency σε κάθε cycle και το number of operations/iteration (pipeline). 

Δημοσ. (επεξεργασμένο)

Οκ got it. Then do it simple...

for (int i = 0; i < MAX_NO_TRIANGLES; i++) { 
    int acc = (Triangles[i].mA == v2 || Triangles[i].mB == v2 || Triangles[i].mC == v2) * 1;
    acc += (Triangles[i].mA == v3 || Triangles[i].mB == v3 || Triangles[i].mC == v3) * 3;
    acc += (Triangles[i].mA == v1 || Triangles[i].mB == v1 || Triangles[i].mC == v1) * 5;

    bool zero = Triangles[i].mA == 0 && Triangles[i].mB == 0 && Triangles[i].mC == 0;

    if (acc == 9) { }
    else if (acc == 4)
    {
        adjTriangle = i;
        i = MAX_NO_TRIANGLES;
    }

    if (i == MAX_NO_TRIANGLES-1 && zero) return 1;
}

Edited and fixed.

Επεξ/σία από jimex
Δημοσ.

 

Οκ got it. Then do it simple...

int acc = (Triangles[i].mA == v2 || Triangles[i].mB == v2 || Triangles[i].mC == v2) * 1;
acc += (Triangles[i].mA == v3 || Triangles[i].mB == v3 || Triangles[i].mC == v3) * 3;
acc += (Triangles[i].mA == v1 || Triangles[i].mB == v1 || Triangles[i].mC == v1) * 5;
 
if (A && 
{
    if (acc == 9) { }
    else if (acc == 4)
    {
        adjTriangle = i;
        i = MAX_NO_TRIANGLES;
    }
}

 

Thanx! Το for loop και το άλλο if; Θα το δοκιμάσω αύριο και θα ενημερώσω.

Δημοσ.

Thanx! Το for loop και το άλλο if; Θα το δοκιμάσω αύριο και θα ενημερώσω.

 

Sorry είχα πάρει copy paste καταλάθος τον κώδικα από τον kercyn λόγω κεκτημένης ταχύτητας και το έγραψα εκεί. Ξαναδές το edit με το δικό σου κώδικα.

 

Επίσης αντί για τα if μπορείς να χρησιμοποιήσεις switch.

  • Like 1
Δημοσ.

Δεν είμαι σίγουρος αν καταλαβαίνω 100% αλλά γενικά για τα nested if χωρίς else μέσα σε τέτοια φάση η προφανής τεχνική είναι να αλλάξεις το

for (...) {
   if (X) {
       if (Y) {
       }
   }
}

σε

for (...) {
    if (!X) { // ΝΟΤ
        continue;
    }

    if (Y) {
    }
}

πράγμα που μπορείς να κάνεις όσες φορές θες οπότε κάνεις unnest τα πάντα αυτής της μορφής.

 

Στη συγκεκριμένη περίπτωση επειδή τα condition που έχεις είναι πολύ συγκεκριμένης οπτικά οικείας μορφής και αν τα αντιστρέψεις η τελική μορφή τους ίσως δεν είναι τόσο εύκολα αναγνωρίσιμη στον αναγνώστη, μπορείς να τα βάλεις σε μεταβλητές (extra name possibly more readable) και να αντιστρέψεις απλά τη μεταβλητή. Οπότε θα κατέληγες σε κάτι του στυλ

for(...) {
    isCondition1 = ...;
    if (!isCondition1) {
        continue;
    }

    isCondition2 = ...;
    if (!isCondition2) {
        continue;
    }

    ....
}

Προσωπικά προτιμάω σχεδόν πάντα αυτό το στυλ όχι μόνο επειδή λιγότερο nesting αλλά και επειδή όταν περάσεις το ένα if αμέσως ξέρεις στο μυαλό σου ότι στη συνέχεια του loop body η τάδε συνθήκη σίγουρα δεν ισχύει. Ενώ με τα nested ποτέ δεν ξέρεις αν με τα 3-4-5 if που έχουμε ανοίξει θα βρούμε κανένα else παρακάτω όπου η τάδε συνθήκη ισχύει ή όχι.

  • Like 1

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...