06/03/13 15:54
dennis87
Ciao a tutti,
devo fare un esercizio che mi chiede
a) Inserimenti di interi in lista. Se la lista è vuota si crea dinamicamente una lista puntata degli interi inseriti dall’utente (0 per terminare l’inserimento). Se la lista non è vuota i nuovi elementi inseriti dall’utente vengono inseriti a partire dalla coda della lista già esistente. In seguito si visualizzano su console gli elementi della lista risultante (dopo l’inserimento) separati da spazi e si ritorna al menù (visualizzare su console la stringa “Nil” nel caso di lista vuota).
b) Eliminazione di interi pari. Si eliminano dalla lista tutti gli elementi con valore intero pari. In
seguito si visualizzano su console gli elementi della lista risultante (dopo l’eliminazione) separati
da spazi e si ritorna al menù (visualizzare su console la stringa “Nil” nel caso di lista vuota).
Ora per il primo punto penso di essere arrivato a conclusione, il secondo ho fatto l'eliminazione al caso se il numero si trova in testa, e si elimina senza problemi, e se il numero si trova in coda, e si elimina senza problemi.
Quando però il numero da eliminare è in coda, esso si elimina, ma se inserisco altri elementi, questi non vengono stampati.
Alltra domanda quale è il metodo per eliminare i numeri che si trovano nel mezzo, cioè non in testa o in coda?
Cioè so che basta modificare il puntatore, ma non capisco come scriverlo.
Questo è il codice che ho scritto fino ad adesso.
EDIT del codice: adesso sembra funzionare, per l'eliminazione di elementi in testa in coda, non se è proprio la soluzione ottimale, ma almeno va. Aspetto consigli su una soluzione meglio...
Codice Editato:
devo fare un esercizio che mi chiede
a) Inserimenti di interi in lista. Se la lista è vuota si crea dinamicamente una lista puntata degli interi inseriti dall’utente (0 per terminare l’inserimento). Se la lista non è vuota i nuovi elementi inseriti dall’utente vengono inseriti a partire dalla coda della lista già esistente. In seguito si visualizzano su console gli elementi della lista risultante (dopo l’inserimento) separati da spazi e si ritorna al menù (visualizzare su console la stringa “Nil” nel caso di lista vuota).
b) Eliminazione di interi pari. Si eliminano dalla lista tutti gli elementi con valore intero pari. In
seguito si visualizzano su console gli elementi della lista risultante (dopo l’eliminazione) separati
da spazi e si ritorna al menù (visualizzare su console la stringa “Nil” nel caso di lista vuota).
Ora per il primo punto penso di essere arrivato a conclusione, il secondo ho fatto l'eliminazione al caso se il numero si trova in testa, e si elimina senza problemi, e se il numero si trova in coda, e si elimina senza problemi.
Quando però il numero da eliminare è in coda, esso si elimina, ma se inserisco altri elementi, questi non vengono stampati.
Alltra domanda quale è il metodo per eliminare i numeri che si trovano nel mezzo, cioè non in testa o in coda?
Cioè so che basta modificare il puntatore, ma non capisco come scriverlo.
Questo è il codice che ho scritto fino ad adesso.
# Title: Esercizio 6 # Author: Dennis Aleandro Boanini # Description: Esercizio di progetto n°6 ################# Data segment menù ########### .data menu1: .asciiz "\n\n1 - Inserimenti di interi in lista. 0 per terminare l'inserimento.\n\n" menu2: .asciiz "2 - Eliminazione di interi dispari.\n\n" ################# Data segment generale ########### end: .asciiz "\nFine del programma!\n" nil: .asciiz "\nNil\n\n" space: .asciiz " " insert: .asciiz "\nInserisci elemento -> " elinsert: .asciiz "\nElementi inseriti -> " inserimento: .asciiz "\nEffettua una scelta -> " test: .asciiz " -- Di test -- " error: .asciiz "\nScelta sbagliata, rieffettua la scelta per favore " creator: .asciiz " \n\n Created by Dennis Aleandro Boanini " coda: .asciiz "\n coda" .align 4 jump_table: .space 8 # jump table array a 4 word che verra' instanziata dal main con gli indirizzi delle label che chiameranno le corrispondenti procedure ################# Code segment ##################### .text .globl main main: la $s1, jump_table #assegnazione ad $s1 dell'indirizzo base della jump_table la $t0, juno #assegnazione a $t0 l'indirizzo della case action juno sw $t0, 0($s1) la $t0, jdue #assegnazione a $t0 l'indirizzo della case action juno sw $t0, 4($s1) #scrittura nella locazione di memoria di indirizzo $s1+4 del valore contenuto in $t0 move $t8 $zero # s0 (= Testa) = 0 move $t9 $zero # s1 (= Coda ) = 0 li $s2, 2 #per controllo se numero pari o dispari menu: #Stampa del menu di selezione la $a0, menu1 #carico l'indirizzo della stringa menu1 in $a0 li $v0, 4 #assegno il codice 4 (print string) a $v0 syscall #stampo la stringa menu1 la $a0, menu2 li $v0, 4 syscall choice: # scelta della procedura o dell'uscita li $v0, 4 # $v0 =codice della print_string la $a0, inserimento # $a0 = indirizzo della stringa syscall # stampa la stringa prompt # legge la scelta li $v0, 5 syscall move $s0, $v0 # $s0=scelta 1, 2, 3 o 4 sle $t0, $s0, $zero # $t0=1 se $s0 <= 0 bne $t0, $zero, choice_err # errore se scelta <=0 li $t0,4 sle $t0, $s0, $t0 beq $t0, $zero, choice_err # errore se scelta >4 branch_case: la $s1, jump_table addi $s0, $s0, -1 # tolgo 1 da scelta perche' prima azione nella jump table (in posizione 0) corrisponde alla prima scelta del case add $t0, $s0, $s0 add $t0, $t0, $t0 # ho calcolato (scelta-1) * 4 add $t0, $t0, $s1 # sommo all'indirizzo della prima case action l'offset calcolato sopra lw $t0, 0($t0) # $t0 = indirizzo a cui devo saltare jr $t0 # salto all'indirizzo calcolato choice_err: li $v0, 4 la $a0, error syscall # stampa la stringa errore j choice # ritorna alla richiesta di inserimento di un numero tra 1 e 4 # prima case action juno: #move $t8 $zero # s0 (= Testa) = 0 #move $t9 $zero # s1 (= Coda ) = 0 bne $t8, $zero, inputloop li $v0, 4 la $a0, nil syscall inputloop: # inizio loop di input; li $v0, 4 la $a0, insert syscall # stampa messaggio li $v0, 5 syscall # legge un intero beq $v0, $zero, print # se l'intero letto e' zero, salta all'etichetta print (stampa) move $t1 $v0 # altrimenti t1=input # inizio inserzione nuovo elemento li $v0, 9 li $a0, 8 #8 byte, 1 per l'intero e uno per il puntatore. syscall # chiamata sbrk: restituisce un blocco di 8 byte, puntato da v0: il nuovo record # vegono riempiti i due campi del nuovo record: sw $t1, 0($v0) # campo intero = t1 sw $zero, 4($v0) # campo elemento-successivo = nil bne $t8, $zero, link_last # se s0!=nil (coda non vuota) vai a link_last move $t8, $v0 # altrimenti (prima inserzione) Testa=Coda=v0 move $t9, $v0 j inputloop # torna all'inizio del loop di input link_last: # se la coda e' non vuota, collega l'ultimo elemento della lista, # puntato da Coda (s1) al nuovo record; dopodiche' modifica Coda # per farlo puntare al nuovo record sw $v0, 4($t9) # il campo elemento successivo dell'ultimo del record prende v0 move $t9, $v0 # Coda = v0 j inputloop print: # loop di stampa di tutti gli elementi della coda, separati da spazi move $t0, $t8 # t0 = Testa. t0 verra' usato come puntatore per scorrere gli elementi della lista li $v0, 4 la $a0, elinsert syscall loop_print: beq $t0, $zero, menu # se t0 == 0 si e' raggiunta la fine della lista e si esce li $v0, 1 # altrimenti si stampa l'elemento corrente. Cioe': lw $a0, 0($t0) # a0 = valore del campo intero dell'elemento corrente (puntato da t0) syscall # stampa valore intero dell'elemento corrente li $v0, 4 la $a0, space syscall # stampa spazio lw $t0, 4($t0) # t0 = valore del campo elemento-successivo dell'elemento corrente (puntato da t0) j loop_print # salta all'inizio del ciclo di stampa j menu jdue: beq $t8, $zero, empty move $t0, $t8 trova: lw $s0, 0($t0) div $s0, $s2 mfhi $s1 beq $s1, $zero, checkTC lw $t0, 4($t0) j trova checkTC: beq $t0, $t8, eliminaT beq $t0, $t9, eliminaC eliminaT: lw $t8, 4($t0) lw $t0, 4($t0) j trova eliminaC: sw $zero, -4($t9) lw $t0, 4($t0) beq $t0, $zero, print j trova empty: li $v0, 4 la $a0, nil syscall j menu
EDIT del codice: adesso sembra funzionare, per l'eliminazione di elementi in testa in coda, non se è proprio la soluzione ottimale, ma almeno va. Aspetto consigli su una soluzione meglio...
Codice Editato:
# Title: Esercizio 6 # Author: Dennis Aleandro Boanini # Description: Esercizio di progetto n°6 ################# Data segment menù ########### .data menu1: .asciiz "\n\n1 - Inserimenti di interi in lista. 0 per terminare l'inserimento.\n\n" menu2: .asciiz "2 - Eliminazione di interi dispari.\n\n" ################# Data segment generale ########### end: .asciiz "\nFine del programma!\n" nil: .asciiz "\nNil\n\n" space: .asciiz " " insert: .asciiz "\nInserisci elemento -> " elinsert: .asciiz "\nElementi inseriti -> " inserimento: .asciiz "\nEffettua una scelta -> " test: .asciiz " -- Di test -- " error: .asciiz "\nScelta sbagliata, rieffettua la scelta per favore " creator: .asciiz " \n\n Created by Dennis Aleandro Boanini " mezzo: .asciiz "\n mezzo" .align 4 jump_table: .space 8 # jump table array a 4 word che verra' instanziata dal main con gli indirizzi delle label che chiameranno le corrispondenti procedure ################# Code segment ##################### .text .globl main main: la $s1, jump_table #assegnazione ad $s1 dell'indirizzo base della jump_table la $t0, juno #assegnazione a $t0 l'indirizzo della case action juno sw $t0, 0($s1) la $t0, jdue #assegnazione a $t0 l'indirizzo della case action juno sw $t0, 4($s1) #scrittura nella locazione di memoria di indirizzo $s1+4 del valore contenuto in $t0 move $t8 $zero # s0 (= Testa) = 0 move $t9 $zero # s1 (= Coda ) = 0 li $s2, 2 #per controllo se numero pari o dispari menu: #Stampa del menu di selezione la $a0, menu1 #carico l'indirizzo della stringa menu1 in $a0 li $v0, 4 #assegno il codice 4 (print string) a $v0 syscall #stampo la stringa menu1 la $a0, menu2 li $v0, 4 syscall choice: # scelta della procedura o dell'uscita li $v0, 4 # $v0 =codice della print_string la $a0, inserimento # $a0 = indirizzo della stringa syscall # stampa la stringa prompt # legge la scelta li $v0, 5 syscall move $s0, $v0 # $s0=scelta 1, 2, 3 o 4 sle $t0, $s0, $zero # $t0=1 se $s0 <= 0 bne $t0, $zero, choice_err # errore se scelta <=0 li $t0,4 sle $t0, $s0, $t0 beq $t0, $zero, choice_err # errore se scelta >4 branch_case: la $s1, jump_table addi $s0, $s0, -1 # tolgo 1 da scelta perche' prima azione nella jump table (in posizione 0) corrisponde alla prima scelta del case add $t0, $s0, $s0 add $t0, $t0, $t0 # ho calcolato (scelta-1) * 4 add $t0, $t0, $s1 # sommo all'indirizzo della prima case action l'offset calcolato sopra lw $t0, 0($t0) # $t0 = indirizzo a cui devo saltare jr $t0 # salto all'indirizzo calcolato choice_err: li $v0, 4 la $a0, error syscall # stampa la stringa errore j choice # ritorna alla richiesta di inserimento di un numero tra 1 e 4 # prima case action juno: #move $t8 $zero # s0 (= Testa) = 0 #move $t9 $zero # s1 (= Coda ) = 0 bne $t8, $zero, inputloop li $v0, 4 la $a0, nil syscall inputloop: # inizio loop di input; li $v0, 4 la $a0, insert syscall # stampa messaggio li $v0, 5 syscall # legge un intero beq $v0, $zero, print # se l'intero letto e' zero, salta all'etichetta print (stampa) move $t1 $v0 # altrimenti t1=input # inizio inserzione nuovo elemento li $v0, 9 li $a0, 8 #8 byte, 1 per l'intero e uno per il puntatore. syscall # chiamata sbrk: restituisce un blocco di 8 byte, puntato da v0: il nuovo record # vegono riempiti i due campi del nuovo record: sw $t1, 0($v0) # campo intero = t1 sw $zero, 4($v0) # campo elemento-successivo = nil bne $t8, $zero, link_last # se s0!=nil (coda non vuota) vai a link_last move $t8, $v0 # altrimenti (prima inserzione) Testa=Coda=v0 move $t9, $v0 j inputloop # torna all'inizio del loop di input link_last: # se la coda e' non vuota, collega l'ultimo elemento della lista, # puntato da Coda (s1) al nuovo record; dopodiche' modifica Coda # per farlo puntare al nuovo record sw $v0, 4($t9) # il campo elemento successivo dell'ultimo del record prende v0 move $t9, $v0 # Coda = v0 j inputloop print: # loop di stampa di tutti gli elementi della coda, separati da spazi move $t0, $t8 # t0 = Testa. t0 verra' usato come puntatore per scorrere gli elementi della lista li $v0, 4 la $a0, elinsert syscall loop_print: beq $t0, $zero, menu # se t0 == 0 si e' raggiunta la fine della lista e si esce li $v0, 1 # altrimenti si stampa l'elemento corrente. Cioe': lw $a0, 0($t0) # a0 = valore del campo intero dell'elemento corrente (puntato da t0) syscall # stampa valore intero dell'elemento corrente li $v0, 4 la $a0, space syscall # stampa spazio lw $t0, 4($t0) # t0 = valore del campo elemento-successivo dell'elemento corrente (puntato da t0) j loop_print # salta all'inizio del ciclo di stampa j menu jdue: beq $t8, $zero, empty move $t0, $t8 trova: lw $s0, 0($t0) div $s0, $s2 mfhi $s1 beq $s1, $zero, checkTC lw $t0, 4($t0) beq $t0, $zero, print j trova checkTC: beq $t0, $t8, eliminaT beq $t0, $t9, eliminaC j eliminaM eliminaT: lw $t8, 4($t0) lw $t0, 4($t0) j trova eliminaC: sw $zero, -4($t0) #lw $t9, -4($t0) addi $t9, $t9, -8 #move $s5, $t0 lw $t0, 4($t0) beq $t0, $zero, print j trova eliminaM: lw $t0, 4($t0) sw $t0, -12($t0) j trova empty: li $v0, 4 la $a0, nil syscall j menu
Ultima modifica effettuata da dennis87 07/03/13 16:53
aaa