Domanda allocazione dinamica array

alessina02

Utente Bronze
2 Gennaio 2022
35
11
0
25
Salve a tutti. Il mio esercizio chiede di inserire in input una stringa di numeri a(n), che si interrompa non appena un numero si ripete.
ESEMPIO: 2 5 8 4 6 3 2, due si ripete e quindi la stringa si interrompe. Il punto è che non capisco come fare ad inizializzare a(n) in modo che "cresca" finchè non trova un doppione
 
Non hai specificato se usi C o C++. Se usi quest'ultimo ti consiglio di usare semplicemente std::vector<int> che gestisce la memoria per te. Se devi farlo in C allora ti serve sicuramente chiamare realloc per aumentare le dimensioni dell'array quando serve chiedere e inserire un altro numero.
 
uso C, e devo inserire carattere per carattere. Idealmente, dovrebbe continuare a farmi inserire numeri all'infinito finchè non ci sono due cifre uguali, allora il doppione chiude la stringa
 
Volendo si può creare un array dinamico con malloc e realloc, come ha detto JunkCoder, ma vista la richiesta estremamente semplice secondo me non è questo il caso. Sicura che non ti basta creare un array sufficientemente grande? Non è che magari è un esercizio sulle linked list? Prima di metterti a studiare una cosa che magari non ti serve, se fossi in te io chiederei spiegazioni al tuo professore.

Se non fosse per il titolo della discussione io ti direi di creare un array di 1 milione di elementi e dare per scontato che l'utente non inserirà così tanti numeri.
 
questo è il testo dell'esercizio

Scrivere un programma che riceva in input una sequenza di interi positivi terminata immettendo un numero gi`a dato
in input; questo ultimo dato non deve essere considerato ma solo fungere da terminatore della sequenza.
Se a0, . . . , an `e la sequenza inserita, sia b0, . . . , bn la sequenza ordinata degli input, in modo tale che la funzione
definita da π(bi) = ai (0 ≤ i ≤ n) sia una permutazione di {b0, . . . , bn}.
Il programma deve scrivere la permutazione π in notazione ciclica. L’output del programma deve essere la sequenza
de cicli di π scritti fra parentesi tonde, ordinati lessicograficamente, omettendo i cicli di lunghezza 1; ad esempio,
all’input
2 3 29 8 12 32 30 3
deve corrispondere l’output
(8 29 12)(30 32)
 
Confermo quanto dicevo prima, secondo me non ti serve creare un array dinamico. Crea un array con qualche migliaio di elementi e assumi che l'utente non inserisca mai così tanti numeri. Facci sapere se hai altri problemi con questo esercizio.
 
Confermo quanto dicevo prima, secondo me non ti serve creare un array dinamico. Crea un array con qualche migliaio di elementi e assumi che l'utente non inserisca mai così tanti numeri. Facci sapere se hai altri problemi con questo esercizio.
Ma così il mio array iniziale avrebbe dentro tutti zeri, giusto? Quindi come faccio a "fermare" la funzione di input quando c'è un doppione se il mio array è formato sempre dallo stesso numero? Non mi entrerebbe proprio nel ciclo "Inserisci dati finchè non trovi un doppione" di cui ho bisogno per iniziare l'esercizio
 
Ultima modifica:
Ma così il mio array iniziale avrebbe dentro tutti zeri, giusto? Quindi come faccio a "fermare" la funzione di input quando c'è un doppione se il mio array è formato sempre dallo stesso numero? Non mi entrerebbe proprio nel ciclo "Inserisci dati finchè non trovi un doppione" di cui ho bisogno per iniziare l'esercizio
Un array non inizializzato, come ogni altra variabile non inizializzata, contiene valori non ben precisati.

Quindi come faccio a "fermare" la funzione di input quando c'è un doppione se il mio array è formato sempre dallo stesso numero?
Devi creare un array molto grande e utilizzarlo come se fosse un array molto piccolo che si ingrandisce man mano. Una cosa del genere.
C:
#include <stdio.h>
#include <stdbool.h>
#define MAXLEN 1024

// return true iff array[0 .. length-1] contains value.
bool contains(int value, int* array, size_t length) {
  for (size_t i = 0; i < length; i++)
    if (array[i] == value) return true;
  return false;
}

int main() {
  int array[MAXLEN];
  size_t length = 0;

  // leggo l'array
  while (length < MAXLEN) {
    int x;
    printf("Inserisci numero: ");
    scanf("%d", &x);
    if (contains(x, array, length)) break;
    array[length++] = x;
  }

  // stampo i suoi elementi
  for (size_t i = 0; i < length; i++)
    printf("array[%d] = %d\n", i, array[i]);

  return 0;
}

Tu dicevi "dovrebbe continuare a farmi inserire numeri all'infinito finchè non ci sono due cifre uguali". Io ho semplificato l'esercizio dicendo: "dovrebbe continuare a farmi inserire numeri finché non ci sono due cifre uguali o finché non ne ho inseriti MAXLEN".
 
Ciao di nuovo!
Ho di nuovo il problema di dover allocare un vettore che "cresce", sempre nello stesso esercizio. Questo è il testo
Scrivere un programma che riceva in input una sequenza di interi positivi terminata immettendo un numero gi`a dato
in input; questo ultimo dato non deve essere considerato ma solo fungere da terminatore della sequenza.
Se a0, . . . , an `e la sequenza inserita, sia b0, . . . , bn la sequenza ordinata degli input, in modo tale che la funzione
definita da π(bi) = ai (0 ≤ i ≤ n) sia una permutazione di {b0, . . . , bn}.
Il programma deve scrivere la permutazione π in notazione ciclica. L’output del programma deve essere la sequenza
de cicli di π scritti fra parentesi tonde, ordinati lessicograficamente, omettendo i cicli di lunghezza 1; ad esempio,
all’input
2 3 29 8 12 32 30 3
deve corrispondere l’output
(8 29 12)(30 32)

Sono arrivata ad inizializzare il vettore p delle permutazioni, ma quando lo stampo ho delle cifre strane perchè il vettore è troppo lungo rispetto alla roba che ci metto dentro, per intenderci.
Inoltre, non ho idea di come inserire le parentesi automaticamente nel punto giusto. Nell'esempio, devo scambiare 8,29,12 e 30,32. Invece nel programma che ho scritto sembra che io debba scambiare tutti e cinque i numeri tra loro







C:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <malloc.h>
#define MAXLEN 1024

// return true iff array[0 .. length-1] contains value.
bool contains(int value, int* array, size_t length) {
  for (size_t i = 0; i < length; i++)
    if (array[i] == value) return true;
  return false;
}


int main() {
  int a[MAXLEN];
  size_t length = 0;

  // leggo l'array
  while (length < MAXLEN) {
    int x;
    scanf("%d", &x);
    if (contains(x, a, length)) break;
    a[length] = x; length++;}

//ordino b
int b[length];
int i,j,min,t;
for (i=0; i<length; i++) b[i]=a[i];

for (i=0; i<length; i++) {min=i;
for (j=i+1; j<length; j++) {if (b[j]<b[min]) min=j;}
t=b[min]; b[min]=b[i]; b[i]=t;}

//Creo il vettore delle permutazioni
int p[length];
int h=0;
for (i=0; i<length; i++) {if (b[i]!=a[i]) {p[h]=b[i]; h++;}
}

 // stampo i suoi elementi
 printf ("\n");
  for (size_t i = 0; i < length; i++)
    printf("%d\t", p[i]);


  return 0;
}
 
int b[length];
int p[length];
Gli array vanno inizializzati con una dimensione costante (un numero o qualcosa dichiarato con define), non con una variabile.
In questi due punti devi scrivere MAXLEN invece che length, altrimenti stai creando VLA invece di array normali.

Sono arrivata ad inizializzare il vettore p delle permutazioni, ma quando lo stampo ho delle cifre strane perchè il vettore è troppo lungo rispetto alla roba che ci metto dentro, per intenderci.
Il problema è che stampi tutti i valori da 0 a length, ma alcuni di questi elementi non sono stati inizializzati. In sostanza, devi fare queste due correzioni:
C:
int b[MAXLEN]; // al posto di int b[length];
int p[MAXLEN] = {-1}; // al posto di int p[length];
Poi quando stampi gli elementi puoi fare così:
C:
for (size_t i = 0; i < length; i++)
    if (p[i] != -1) printf("%d\t", p[i]);

Inoltre, non ho idea di come inserire le parentesi automaticamente nel punto giusto. Nell'esempio, devo scambiare 8,29,12 e 30,32. Invece nel programma che ho scritto sembra che io debba scambiare tutti e cinque i numeri tra loro
Per ora è ancora presto preoccuparsi delle parentesi. Il tuo array p non è il vettore delle permutazioni e, anche se lo fosse, il vettore delle permutazioni non è l'output richiesto dall'esercizio. Secondo me non hai ancora capito come calcolare quello che ti chiede l'esercizio perché la soluzione è un po' più complicata rispetto a quello che stai facendo. Inizia a pensare a come lo risolveresti a mano e poi prova a scrivere il codice. Se non riesci a scrivere il codice scrivici almeno cosa faresti con carta e penna perché il modo in cui l'ho risolto io potrebbe essere diverso rispetto al modo in cui lo risolveresti tu.
 
  • Mi piace
Reazioni: --- Ra ---