Διαδρομές
/
Go
Go
/
Ασκήσεις
/
Κόλπα με τραπουλόχαρτα
Κόλπα με τραπουλόχαρτα

Κόλπα με τραπουλόχαρτα

Άσκηση εκμάθησης

Εισαγωγή

Slices

Τα slices στη Go μοιάζουν με τις λίστες ή τους πίνακες σε άλλες γλώσσες. Περιέχουν αρκετά στοιχεία ενός συγκεκριμένου τύπου (ή διεπαφής).

Τα slices στη Go βασίζονται σε πίνακες. Οι πίνακες έχουν σταθερό μέγεθος. Ένα slice, από την άλλη, είναι μια δυναμικά μεταβαλλόμενου μεγέθους, ευέλικτη προβολή των στοιχείων ενός πίνακα.

Ένα slice γράφεται σαν []T, όπου T είναι ο τύπος των στοιχείων του slice:

var empty []int                 // an empty slice
withData := []int{0,1,2,3,4,5}  // a slice pre-filled with some data

Μπορείς να διαβάσεις ή να ορίσεις ένα στοιχείο σε μια δεδομένη θέση με βάση το μηδέν χρησιμοποιώντας τη σημειογραφία με αγκύλες:

withData[1] = 5
x := withData[1] // x is now 5

Μπορείς να δημιουργήσεις ένα νέο slice από ένα υπάρχον slice παίρνοντας ένα εύρος στοιχείων. Και πάλι με τη σημειογραφία με αγκύλες, αλλά αυτή τη φορά προσδιορίζεις και την αρχική θέση (συμπεριλαμβανομένης) και την τελική θέση (μη συμπεριλαμβανομένης). Αν δεν προσδιορίσεις αρχική θέση, χρησιμοποιείται το 0 ως προεπιλογή. Αν δεν προσδιορίσεις τελική θέση, χρησιμοποιείται το μήκος του slice ως προεπιλογή.

newSlice := withData[2:4]
// => []int{2,3}
newSlice := withData[:2]
// => []int{0,1}
newSlice := withData[2:]
// => []int{2,3,4,5}
newSlice := withData[:]
// => []int{0,1,2,3,4,5}

Μπορείς να προσθέσεις στοιχεία σε ένα slice χρησιμοποιώντας τη συνάρτηση append. Παρακάτω προσθέτουμε το 4 και το 2 στο slice a.

a := []int{1, 3}
a = append(a, 4, 2)
// => []int{1,3,4,2}

Η append επιστρέφει πάντα ένα νέο slice, και όταν θέλουμε απλώς να προσθέσουμε στοιχεία σε ένα υπάρχον slice, συνηθίζεται να το αναθέτουμε ξανά στη μεταβλητή slice που περνάμε ως πρώτο όρισμα, όπως κάναμε παραπάνω.

Η append μπορεί επίσης να χρησιμοποιηθεί για τη συγχώνευση δύο slices:

nextSlice := []int{100,101,102}
newSlice  := append(withData, nextSlice...)
// => []int{0,1,2,3,4,5,100,101,102}

Συναρτήσεις μεταβλητού αριθμού ορισμάτων

Συνήθως, οι συναρτήσεις στη Go δέχονται μόνο έναν σταθερό αριθμό ορισμάτων. Ωστόσο, στη Go μπορείς επίσης να γράψεις συναρτήσεις μεταβλητού αριθμού ορισμάτων.

Μια συνάρτηση μεταβλητού αριθμού ορισμάτων δέχεται μεταβλητό αριθμό ορισμάτων.

Αν ο τύπος της τελευταίας παραμέτρου σε έναν ορισμό συνάρτησης έχει ως πρόθεμα την έλλειψη ..., τότε η συνάρτηση μπορεί να δεχτεί οποιονδήποτε αριθμό ορισμάτων για αυτήν την παράμετρο.

func find(a int, b ...int) {
    // ...
}

Στη συνάρτηση παραπάνω, η παράμετρος b είναι μεταβλητού αριθμού ορισμάτων και μπορούμε να περάσουμε 0 ή περισσότερα ορίσματα στο b.

find(5, 6)
find(5, 6, 7)
find(5)
Caution

Η παράμετρος μεταβλητού αριθμού ορισμάτων πρέπει να είναι η τελευταία παράμετρος της συνάρτησης.

Οι συναρτήσεις μεταβλητού αριθμού ορισμάτων λειτουργούν μετατρέποντας τον μεταβλητό αριθμό ορισμάτων σε ένα slice του τύπου της παραμέτρου μεταβλητού αριθμού ορισμάτων.

Ακολουθεί ένα παράδειγμα υλοποίησης μιας συνάρτησης μεταβλητού αριθμού ορισμάτων.

func find(num int, nums ...int) {
    fmt.Printf("type of nums is %T\n", nums)

    for i, v := range nums {
        if v == num {
            fmt.Println(num, "found at index", i, "in", nums)
            return
        }
    }

    fmt.Println(num, "not found in ", nums)
}

func main() {
    find(89, 90, 91, 95)
    // =>
    // type of nums is []int
    // 89 not found in  [90 91 95]

    find(45, 56, 67, 45, 90, 109)
    // =>
    // type of nums is []int
    // 45 found at index 2 in [56 67 45 90 109]

    find(87)
    // =>
    // type of nums is []int
    // 87 not found in  []
}

Στη γραμμή find(89, 90, 91, 95) του παραπάνω προγράμματος, ο μεταβλητός αριθμός ορισμάτων στη συνάρτηση find είναι τα 90, 91 και 95. Η συνάρτηση find περιμένει μια παράμετρο μεταβλητού αριθμού ορισμάτων τύπου int μετά το num. Επομένως, αυτά τα τρία ορίσματα θα μετατραπούν από τον μεταγλωττιστή σε ένα slice τύπου int, το []int{90, 91, 95}, και μετά θα περαστούν στη συνάρτηση find ως nums.

Μερικές φορές έχεις ήδη ένα slice και θέλεις να το περάσεις σε μια συνάρτηση μεταβλητού αριθμού ορισμάτων. Αυτό γίνεται περνώντας το slice ακολουθούμενο από .... Έτσι λες στον μεταγλωττιστή να χρησιμοποιήσει το slice ως έχει μέσα στη συνάρτηση μεταβλητού αριθμού ορισμάτων. Το βήμα που περιγράφηκε παραπάνω, όπου δημιουργείται ένα slice, απλώς παραλείπεται σε αυτήν την περίπτωση.

list := []int{1, 2, 3}
find(1, list...) // "find" defined as shown above

Οδηγίες

Ως επίδοξη μάγισσα, η Elyse θέλει να εξασκηθεί στα βασικά. Έχει μια στοίβα με κάρτες που θέλει να χειριστεί.

Για να κάνει τα πράγματα λίγο πιο εύκολα, χρησιμοποιεί μόνο τις κάρτες από το 1 έως το 10.

1. Δημιούργησε ένα slice με συγκεκριμένες κάρτες

Όταν εξασκείται με τις κάρτες της, στην Elyse αρέσει να ξεκινά με τις τρεις αγαπημένες της κάρτες από την τράπουλα: το 2, το 6 και το 9. Γράψε μια συνάρτηση FavoriteCards που επιστρέφει ένα slice με αυτές τις κάρτες με αυτή τη σειρά.

cards := FavoriteCards()
fmt.Println(cards)
// Output: [2 6 9]

2. Πάρε μια κάρτα από μια στοίβα

Επίστρεψε την κάρτα στη θέση index από τη στοίβα που δίνεται.

card := GetItem([]int{1, 2, 4, 1}, 2) // card == 4

Αν η θέση είναι εκτός ορίων (δηλαδή αν είναι αρνητική ή μετά το τέλος της στοίβας), θέλουμε να επιστρέφουμε το -1:

card := GetItem([]int{1, 2, 4, 1}, 10) // card == -1
Note

Κατά σύμβαση στη Go, επιστρέφεται ένα σφάλμα αντί να επιστραφεί μια τιμή "εκτός ορίων". Εδώ η τιμή "εκτός ορίων" είναι το -1, όταν αναμένεται ένας θετικός ακέραιος. Όταν επιστρέφεται ένα σφάλμα, θεωρείται ιδιωματικό να επιστρέφεται και το zero value μαζί με το σφάλμα. Η επιστροφή ενός σφάλματος μαζί με τη σωστή τιμή επιστροφής θα καλυφθεί σε επόμενη άσκηση.

3. Αντάλλαξε μια κάρτα στη στοίβα

Αντάλλαξε την κάρτα στη θέση index με τη νέα κάρτα που δίνεται και επίστρεψε την τροποποιημένη στοίβα. Σημείωσε ότι αυτό θα τροποποιήσει το slice εισόδου, κάτι που είναι η αναμενόμενη συμπεριφορά.

index := 2
newCard := 6
cards := SetItem([]int{1, 2, 4, 1}, index, newCard)
fmt.Println(cards)
// Output: [1 2 6 1]

Αν η θέση είναι εκτός ορίων (δηλαδή αν είναι αρνητική ή μετά το τέλος της στοίβας), θέλουμε να προσθέσουμε τη νέα κάρτα στο τέλος της στοίβας:

index := -1
newCard := 6
cards := SetItem([]int{1, 2, 4, 1}, index, newCard)
fmt.Println(cards)
// Output: [1 2 4 1 6]

4. Πρόσθεσε κάρτες στην κορυφή της στοίβας

Πρόσθεσε την κάρτα ή τις κάρτες που ορίζονται στην παράμετρο value στην κορυφή της στοίβας.

slice := []int{3, 2, 6, 4, 8}
cards := PrependItems(slice, 5, 1)
fmt.Println(cards)
// Output: [5 1 3 2 6 4 8]

Αν δεν δοθεί όρισμα για την παράμετρο value, τότε το αποτέλεσμα είναι ίσο με το αρχικό slice.

slice := []int{3, 2, 6, 4, 8}
cards := PrependItems(slice)
fmt.Println(cards)
// Output: [3 2 6 4 8]

5. Αφαίρεσε μια κάρτα από τη στοίβα

Αφαίρεσε την κάρτα στη θέση index από τη στοίβα και επίστρεψε τη στοίβα. Σημείωσε ότι αυτό μπορεί να τροποποιήσει το slice εισόδου, κάτι που είναι εντάξει.

cards := RemoveItem([]int{3, 2, 6, 4, 8}, 2)
fmt.Println(cards)
// Output: [3 2 4 8]

Αν η θέση είναι εκτός ορίων (δηλαδή αν είναι αρνητική ή μετά το τέλος της στοίβας), θέλουμε να αφήσουμε τη στοίβα όπως είναι:

cards := RemoveItem([]int{3, 2, 6, 4, 8}, 11)
fmt.Println(cards)
// Output: [3 2 6 4 8]
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
Go Exercism

Έτοιμος να ξεκινήσεις την άσκηση Κόλπα με τραπουλόχαρτα;

Γράψου στο Exercism για να μάθεις και να κατακτήσεις Go με 34 έννοιες165 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.