RISOLTO Eseguire ricerca in un algoritmo

Stato
Discussione chiusa ad ulteriori risposte.

AxelR

Nuovo Utente
5
0
Ciao a tutti,
mi servirebbe una dritta!
In un un algoritmo in cui è presente un vettore composto da 12 numeri che saranno scelti casualmente tra un min di 38 e un massimo di 55, dovrei inserire un controllo di questi numeri che alla fine mi dia in output i numeri non presenti in quel vettore (quindi i numeri tra 38 e 55 non selezionati per popolarlo).
Io utilizzerò Flowgorithm per creare questo algoritmo.
Grazie mille.
 

Moffetta88

Moderatore
Staff Forum
Utente Èlite
20,558
12,947
CPU
i5-4690
Dissipatore
DEEPCOOL CAPTAIN 240EX
Scheda Madre
MSI Z97 U3 PLUS
HDD
KINGSTON SSD KC400 240GB
RAM
24GB BALLISTIX SPORT @2133MHz
GPU
STRIX GTX980 DC2OC
Audio
INTEGRATA
Monitor
AOC G2590VXQ
PSU
BEQUIET! System Power 7 500W
Case
DEEPCOOL MATREXX 55
Periferiche
NESSUNA
Net
EOLO 100
OS
UBUNTU/WINDOWS11
Ok, hai bisogno un flowchart quindi...
Tu fin dove sei arrivato? perchè qui sul forum non facciamo i compiti agli altri, ma aiutiamo
 

AxelR

Nuovo Utente
5
0
Ciao! Si esattamente.
Sono arrivato, una volta fatte le varie dichiarazioni, a popolare il vettore con il criterio di cui sopra,
Poi mi sono perso nel cercare di trovare un criterio con cui effettuare la verifica.
Allego le immagini del diagramma per com'è ora.
Grazie
 

Allegati

  • 1.png
    1.png
    26.8 KB · Visualizzazioni: 19
  • 2.png
    2.png
    41.8 KB · Visualizzazioni: 19

AxelR

Nuovo Utente
5
0
Inserisco la richiesta completa dell'esecuzione dell'algoritmo:
- Realizzare un vettore di dimensione 11 con numeri casuali interi compresi tra 38 e 55 e visualizzare il vettore in output: e questo credo sia corretto quanto ho scritto;
- Visualizzare in output i numeri non presenti nel vettore (considerando i valori possibili tra 38 e 55): qui mi servirebbe una mano, in quanto non so bene come ricercare un numero in un vettore.
Ringrazio.
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
- Visualizzare in output i numeri non presenti nel vettore (considerando i valori possibili tra 38 e 55): qui mi servirebbe una mano, in quanto non so bene come ricercare un numero in un vettore.

Ti rispondo a livello logico di algoritmo: è un tipo di problema che generalizzando puoi affrontare in due modi.

Su un insieme piccolo scorri da inizio a quando lo trovi (o alla fine, se non esiste) con il vettore di partenza. Scorri in un tempo lineare, avendo N elementi.

In caso di molti elementi il vettore lo si ordina. Ordinando è molto più comodo, se usi per esempio la ricerca dicotomica li guardi tutti in log base 2 di n (in pratica, dimezzi ogni volta, dovresti guardare l'algoritmo per capire che intendo, se non lo conosci).

Eg. se hai (53,41,45,44,57,39), lo ordini ottenendo (39,41,44,45,53,57). Supponiamo devi trovare 57.

Usando la ricerca dicotomica, dividi per due e inizi quindi da 44. 44 è minore di 57, quindi la parte a sx viene scartata, e il vettore che consideri sarà (45,53,57).
Dividi per 2 e prendi 53, che non è il valore che cerchi ed è minore. A questo punto vai ancora a dx e romani con 1 solo elemento che è anche quello corretto

Se ricerchi in maniera lineare banalmente scorri tutto da inizio a fine, appunto.

Non so se è quello che ti interessava capire però 😅
 

Hero467

Utente Attivo
689
404
OS
I use ARCH btw
Si, tenete conto che sta usando flowgorithm. Adesso, io ho usato poco quel programma, ma dal poco che l'ho usato era molto limitato. Ed utilizzava una sintassi derivata dal c, quindi niente hash table
 

M1n021

Nuovo Utente
147
68
Si, tenete conto che sta usando flowgorithm. Adesso, io ho usato poco quel programma, ma dal poco che l'ho usato era molto limitato. Ed utilizzava una sintassi derivata dal c, quindi niente hash table
Non conosco il programma in questione, ma alla fine per quello che intendo basta un semplice array di (55-38+1) elementi booleani inizializzati a 0. Nel momento in cui viene estratto un numero casuale basterà settare il corrispondente elemento dell'array a 1.
 

ilfe98

Moderatore
Staff Forum
Utente Èlite
3,052
1,278
CPU
Intel i7 7700K
Dissipatore
Bequiet Dark rock pro 4
Scheda Madre
Msi pc mate z270
HDD
Seagate barracuda 1tb, silicon power NVME 500gb
RAM
Patriot viper steel 3733Mhz
GPU
Inno 3d gtx 1080 herculez design
Monitor
Asus mg279q
PSU
Corsair HX750
Case
Itek lunar 23
Net
Tiscali ftth
OS
windows 10,mint,debian,Arch linux
Inserisco la richiesta completa dell'esecuzione dell'algoritmo:
- Realizzare un vettore di dimensione 11 con numeri casuali interi compresi tra 38 e 55 e visualizzare il vettore in output: e questo credo sia corretto quanto ho scritto;
- Visualizzare in output i numeri non presenti nel vettore (considerando i valori possibili tra 38 e 55): qui mi servirebbe una mano, in quanto non so bene come ricercare un numero in un vettore.
Ringrazio.
Allora per farla davvero spiccia puoi fare anche così:
Crei il tuo vettore di 11 elementi, ed un vettore booleano di 17 elementi(55-38). Per ogni numero letto nel primo vettore inserisci un uno nella casella del secondo vettore:
Esempio leggi 38 vai ad inserire in posizione 38-38 (0) un uno. Poi leggo 45, quindi faccio 45-38=7. In posizione 7 inserisco 1. Alla fine gli 0 rappresentano i numeri non presenti.
È efficiente? No. Funziona? Sì. Ci sono altri modi? Assolutamente sì, ma questo è facilissimo e adatto ai beginner :)
Consiglio una lettura di hash table e trie
 
  • Mi piace
Reazioni: sp3ctrum

M1n021

Nuovo Utente
147
68
Allora per farla davvero spiccia puoi fare anche così:
Crei il tuo vettore di 11 elementi, ed un vettore booleano di 17 elementi(55-38). Per ogni numero letto nel primo vettore inserisci un uno nella casella del secondo vettore:
Esempio leggi 38 vai ad inserire in posizione 38-38 (0) un uno. Poi leggo 45, quindi faccio 45-38=7. In posizione 7 inserisco 1. Alla fine gli 0 rappresentano i numeri non presenti.
È efficiente? No. Funziona? Sì. Ci sono altri modi? Assolutamente sì, ma questo è facilissimo e adatto ai beginner :)
Consiglio una lettura di hash table e trie
In pratica sono le stesse cose che ho detto io:
Implementando una sorta di tabella hash, il controllo diventa immediato.
.... alla fine per quello che intendo basta un semplice array di (55-38+1) elementi booleani inizializzati a 0. Nel momento in cui viene estratto un numero casuale basterà settare il corrispondente elemento dell'array a 1.
In ogni caso vale la pena precisare che gli elementi dell'array booleano devono essere 18 (55-38+1).

P.S.
Perché dici che non è efficiente?, Se parliamo di efficienza temporale (che a mio modo di vedere è l'unica di cui ha senso parlare in un contesto del genere), penso che sia impossibile fare di meglio...
 
  • Mi piace
Reazioni: ilfe98

AxelR

Nuovo Utente
5
0
Ciao a tutti, ringrazio per le risposte!
Intanto preciso anche io che è circa una settimana che mi sono approcciato a questo mondo, quindi le mie basi sono pressochè nulle!
Quindi quanto proposto da ilfe98 nella mia testa ha un senso e l'ho capito, ora devo metterlo in pratica, però mi dovete un attimo guidare.

Vi riporto la prima parte codificata dal programma in C++, che magari vi risulta più comprensibile:

int main() {
srand(time(0)); //Seed random number generator

int v, min, a, c, num;
int vET[12];
int vETO[18];

a = 38;
for (v = 0; v <= 11; v++) {
vET[v] = rand() % 17 + 38;
}

for (c = 0; c <= 17; c++) {
vETO[c] = a;
a = a + 1;
}

Fino a questo punto ho creato un vettore intero di dimensione 11 e l'ho popolato con numeri casuali pescati dal range 38 - 55.
Poi ho creato un altro vettore intero di dimensione 18, nel quale sono andato ad inserire dal 38 al 55 in ogni posizione (non so bene se possa servire a qualcosa, nella mia idea serviva per termine di confronto).
Ora stando a quanto proposto. dovrei iniziare un vettore boleano simile al secondo, che leggendo un po' mi pare accetti sono true/false o 0/1 come valore, e in questo memorizzare la presenza/assenza del numero nel primo vettore.
Per farlo quindi dovrei mettere in confronto i due. facendo ciclare tutti i valore del primo per ogni valore del secondo, alla fine dove ho 0 vuol dire che quel numero non è presente nel primo vettore, giusto?
Ecco sarei un po' in difficoltà a mettere insieme il tutto, viste le mie scarse competenze! Portate pazienza!
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Rileggendo la richiesta mi sono accorto di averla letta male: ho letto la ricerca di 1 elemento nel vettore.
Ora riesco a dare una spiegazione alla vostra soluzione 😁

Btw, il popolamento va bene, l'altro ciclo non ti serve.
La tabella booleana la riempi scorrendo il tuo array randomico.

L'array booleano lo inizializzi come:

int table[18] = {0};

Poi ti fai un ciclo sull'altro array (quello casuale). Quindi andrai a fare tipo 43-38=5. Questo sarà l'indice dell'array booleano da settare a 1.

Penso sia questo ciò che dicono sopra.

Invece di settarli a 0/1 potresti inizializzarlo con i nr del tuo range. Quando becchi un elemento lo metti a 0 in questa mappa.

Così come vantaggio hai che scorrendo ancora questo Array, tutti i valori >0 sono quelli non presenti nell'array.

Cambia poco, se usi 0/1 è comunque semplice risalirci.
 

AxelR

Nuovo Utente
5
0
Ciao a tutti,
credo di essere arrivato alla risoluzione!
Dato che le mie conoscenze in merito (ripeto) sono limitate, mi sono concentrato su quello che so (e il concetto booleano ancora non mi è chiaro), per cui ho utilizzato gli operato basilari per mettere insieme la verifica.
Il risultato è questo, vi metto la codifica in C++, nel caso vi interessasse:

C++:
#include <iostream>
#include <sstream>
#include <string>
#include <cstdlib>
#include <cmath>
#include <ctime>

using namespace std;

// Headers
string toString (double);
int toInt (string);
double toDouble (string);

int main() {
    srand(time(0));   //Seed random number generator
    
    int i, j, find, cont, num;
    int v[11];

    cont = 1;
    num = 1;
    for (i = 0; i <= 10; i++) {
        v[i] = rand() % 17 + 38;
        cout << "Il " << cont << "°" << " valore scelto è " << v[i] << endl;
        cont = cont + 1;
    }
    for (i = 38; i <= 55; i++) {
        find = 0;
        for (j = 0; j <= 10; j++) {
            if (v[j] == i) {
                find = 1;
            }
        }
        if (find == 0) {
            cout << "Il " << num << "°" << " valore non presente è " << i << endl;
            num = num + 1;
        }
    }
    return 0;
}

// The following implements type conversion functions.
string toString (double value) { //int also
    stringstream temp;
    temp << value;
    return temp.str();
}

int toInt (string text) {
    return atoi(text.c_str());
}

double toDouble (string text) {
    return atof(text.c_str());
}
 

M1n021

Nuovo Utente
147
68
Alcune osservazioni:

- quelle funzioni sono inutili (infatti non le utilizzi) e di conseguenza anche alcune delle librerie che hai incluso;
- dal momento che i numeri casuali devono appartenere all'intervallo [38;55] la formula corretta da utilizzare è

rand() % 18 + 38

- nel momento in cui poni find=1 puoi anche uscire dal ciclo for con l'istruzione break;
- in ogni caso volendo seguire il tuo algoritmo farei qualcosa del genere:

C++:
#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
    srand(time(0));

    const int MIN = 38;
    const int MAX = 55;
    const int DIM_1 = 12;
    const int DIM_2 = MAX - MIN + 1;

    int v[DIM_1];

    for(int i = 0; i < DIM_1; ++i)
    {
        v[i] = rand() % DIM_2 + MIN;
        cout << v[i] << " ";
    }
    cout << endl;
    for(int i = MIN, j; i <= MAX; ++i)
    {
        for(j = 0; j < DIM_1 && v[j] != i; ++j);
        if(j == DIM_1)
        {
            cout << i << " ";
        }
    }
}

- seguendo invece l'idea che ho proposto nei precedenti post:

C++:
#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
    srand(time(0));

    const int MIN = 38;
    const int MAX = 55;
    const int DIM_1 = 12;
    const int DIM_2 = MAX - MIN + 1;

    int v[DIM_1];
    int u[DIM_2] = {0};

    for(int i = 0; i < DIM_1; ++i)
    {
        v[i] = rand() % DIM_2 + MIN;
        u[v[i] - MIN] = 1;
        cout << v[i] << " ";
    }
    cout << endl;
    for(int i = MIN; i <= MAX; ++i)
    {
        if(u[i - MIN] == 0)
        {
            cout << i << " ";
        }
    }
}
 

bigendian

Utente Attivo
751
432
OS
Linux
ottimo, o anche in C

Codice:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

static int v[56];

int main()
{
        int i, c = 0;

        srand(time(0));

        do {
                i = rand() % 100;
                if (i < 38 || i > 55)
                        continue;
                v[i]++;
                c++;
        } while (c < 10);

        for (i = 38; i <= 55; i++) {
                if (!v[i])
                        printf("il numero %d non e' nella serie\n", i);
        }

        return 0;
}
 
Stato
Discussione chiusa ad ulteriori risposte.

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili