Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Samsung Galaxy S25 Edge: il top di gamma ultrasottile e leggerissimo. La recensione
Samsung Galaxy S25 Edge: il top di gamma ultrasottile e leggerissimo. La recensione
Abbiamo provato il nuovo Galaxy S25 Edge, uno smartphone unico per il suo spessore di soli 5,8 mm e un peso super piuma. Parliamo di un device che ha pro e contro, ma sicuramente si differenzia dalla massa per la sua portabilità, ma non senza qualche compromesso. Ecco la nostra prova completa.
HP Elitebook Ultra G1i 14 è il notebook compatto, potente e robusto
HP Elitebook Ultra G1i 14 è il notebook compatto, potente e robusto
Pensato per il professionista sempre in movimento, HP Elitebook Ultra G1i 14 abbina una piattaforma Intel Core Ultra 7 ad una costruzione robusta, riuscendo a mantenere un peso contenuto e una facile trasportabilità. Ottime prestazioni per gli ambiti di produttività personale con un'autonomia lontano dalla presa di corrente che permette di lavorare per tutta la giornata
Microsoft Surface Pro 12 è il 2 in 1 più compatto e silenzioso
Microsoft Surface Pro 12 è il 2 in 1 più compatto e silenzioso
Basato su piattaforma Qualcomm Snapdragon X Plus a 8 core, il nuovo Microsoft Surface Pro 12 è un notebook 2 in 1 molto compatto che punta sulla facilità di trasporto, sulla flessibilità d'uso nelle differenti configurazioni, sul funzionamento senza ventola e sull'ampia autonomia lontano dalla presa di corrente
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 28-02-2010, 13:03   #1
ideafissa
Member
 
Iscritto dal: Sep 2004
Messaggi: 113
[C#] problema alberi

Ciao ragazzi, volevo chiedervi se potreste aiutarmi, devo fare un progettino in Visual Studio 2010 che implementa in modo semplice in C# i due problemini qui sotto. Va bene un progetto console UI.

Allora, supponiamo di avere una struttura ad albero (per esempio un albero genealogico), mi servrebbe una routine che conta i nodi. Inoltre mi servirebbe anche una routine che elenca i nodi livello per livello per esempio: tutti i bisnonni, tutti i nonni, tutti i genitori e tutta la generazione corrente.

Mi dareste una mano? grazi
ideafissa è offline   Rispondi citando il messaggio o parte di esso
Old 28-02-2010, 20:27   #2
nikel
Senior Member
 
L'Avatar di nikel
 
Iscritto dal: Mar 2006
Città: Milano
Messaggi: 832
non so se si possano fare in c#

ma io direi.... liste!

una volta che hai definito il tuo "tipo"

per contare i nodi / i nodi allo stesso livello

ti basta contare i puntatori diversi da null
nikel è offline   Rispondi citando il messaggio o parte di esso
Old 01-03-2010, 11:15   #3
ideafissa
Member
 
Iscritto dal: Sep 2004
Messaggi: 113
ops doppio post...

Ultima modifica di ideafissa : 01-03-2010 alle 11:29.
ideafissa è offline   Rispondi citando il messaggio o parte di esso
Old 01-03-2010, 11:17   #4
ideafissa
Member
 
Iscritto dal: Sep 2004
Messaggi: 113
Ho buttato giù questo codice... ditemi cosa ne pensate e dove sono gli eventuali errori... Grazie!!!

Codice:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication7
{
       class Program
   {
       public struct TreeNode
       {
           int item;         // The data in this node.
           public TreeNode* left;   // Pointer to the left subtree.
           public TreeNode* right;  // Pointer to the right subtree.
       }

       unsafe int countNodes(TreeNode* root)
       {
           // Count the nodes in the binary tree to which
           // root points, and return the answer.
           if (root == null)
               return 0;  // The tree is empty.  It contains no nodes.
           else
           {
               int count = 1;   // Start by counting the root.
               count += countNodes(root->left);  // Add the number of nodes in the left subtree.
               count += countNodes(root->right); // Add the number of nodes in the right subtree.
               return count;  // Return the total.
           }
       }
       int Max(int a, int b)
       {
           if (a > b)
           {
               return a;
           }
           else
           {
               return b;
           }
       }
       unsafe int TreeDeep(TreeNode* root)
       {
           int l, r;

           if (root == null)
           {
               return 0;   // Tree is empty => TreeDeep = 0
           }
           else
           {
               l = TreeDeep(root->left); // Calculation of depth of left subtree
               r = TreeDeep(root->right); // Calculate of depth of right subtree
               return (Max(l, r)+1); // Tree's overall depth is > 1
           }
       }

       unsafe int contNodeSameLevel(TreeNode* root, int h)
       {

           if (root == null)
           {
               return 0;
           }
           if (h == 0)
           {
               return 1;
           }
           else
           {
               return contNodeSameLevel(root->left, h - 1) + contNodeSameLevel(root->right, h - 1);
           }
                     }

            static void Main(string[] args)
       {
       }
   }
}
ideafissa è offline   Rispondi citando il messaggio o parte di esso
Old 01-03-2010, 11:37   #5
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12814
Ti dico solo una cosa, non c'è alcun bisogno di usare unsafe, né i puntatori.

Se non sbaglio puoi creare la struttura nell'heap e usare i riferimenti ad essa, usando il costrutto new, tipo:

Codice:
var root = new TreeNode();
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 01-03-2010, 11:47   #6
ideafissa
Member
 
Iscritto dal: Sep 2004
Messaggi: 113
Quote:
Originariamente inviato da WarDuck Guarda i messaggi
Ti dico solo una cosa, non c'è alcun bisogno di usare unsafe, né i puntatori.

Se non sbaglio puoi creare la struttura nell'heap e usare i riferimenti ad essa, usando il costrutto new, tipo:

Codice:
var root = new TreeNode();
Spiegami meglio questa cosa, sono nuovo di c#...
ideafissa è offline   Rispondi citando il messaggio o parte di esso
Old 01-03-2010, 12:07   #7
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12814
Quote:
Originariamente inviato da ideafissa Guarda i messaggi
Spiegami meglio questa cosa, sono nuovo di c#...
Gli oggetti in C# si gestiscono tramite riferimenti ad essi.

Ad esempio:

Codice:
class Person {
    string nome;
    string cognome;
}

f(Person p) {
    p.nome = "A";
    p.cognome = "B";
}

main() {
   Person p = new Person(); // p è un riferimento all'oggetto Person creato nell'heap

   f(p); // si passa il riferimento p

   // p.nome varrà "A"
   // p.cognome varrà "B"
}
La struct è un oggetto più leggero... EDIT

http://msdn.microsoft.com/en-us/libr...8VS.71%29.aspx

A quanto leggo viene sempre allocato nello stack e il suo passaggio avviene sempre per valore (quindi quando la passi ad un metodo viene fatta una copia, le modifiche si riflettono solo all'interno del metodo).

Cmq per il tuo scopo forse è il caso di usare una classe.

Ultima modifica di WarDuck : 01-03-2010 alle 12:16.
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 01-03-2010, 12:53   #8
ideafissa
Member
 
Iscritto dal: Sep 2004
Messaggi: 113
grazie, mi metto subito all'opera!
ideafissa è offline   Rispondi citando il messaggio o parte di esso
Old 01-03-2010, 19:06   #9
ideafissa
Member
 
Iscritto dal: Sep 2004
Messaggi: 113
Ho prodotto questo codice:
Codice:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication7
{

    class TreeNode// Un albero binario che memorizza un elemento ed è collegato ad altri tre nodi, 2 figli e un genitore
    {
        private int value;
        private TreeNode leftChild;
        private TreeNode rightChild;
        private TreeNode parent;
        private BinaryTree tree;

        public virtual int Value
        {
            get { return value; }
            set { this.value = value; }
        }
                    
        public virtual TreeNode LeftChild //Recupera o setta il valore del nodo sinistro
        {
            get { return leftChild; }
            set { leftChild = value; }
        }

        public virtual TreeNode RightChild //Recupera o setta il valore del nodo destro
        {
            get { return rightChild; }
            set { rightChild = value; }
        }
        
                
        public virtual TreeNode Parent //Recupera o setta il valore del nodo genitore
        {
            get { return parent; }
            set { parent = value; }
        }

        /// <summary>
        /// Gets or sets the Binary Tree the node belongs to
        /// </summary>
        public virtual BinaryTree Tree
        {
            get { return tree; }
            set { tree = value; }
        }
        
        public TreeNode(int value) // Istanzia un nuovo nodo
        {
            this.value = value;
        }
    }

    class BinaryTree //Struttura dati
    {
        private TreeNode head;
        private int size;
      
        public virtual int Count //Restituisce il numero di elementi contenuti 
        {
            get { return size; }
        }
                
        public BinaryTree() //Istanzia un nuovo albero
        {
            head = null;
            size = 0;
        }

        public virtual void Add(TreeNode node) //Inserisce un nuovo nodo nell'albero
        {
            if (this.head == null) 
            {
                this.head = node; 
                node.Tree = this;
                size++;
            }
            else
            {
                if (node.Parent == null)
                    node.Parent = head; 

                if (node.Value < node.Parent.Value) //Se il valore del nodo é inferiore a quello del genitore inserisce il nuovo nodo a sinistra
                {
                    if (node.Parent.LeftChild == null)
                    {
                        node.Parent.LeftChild = node; 
                        size++;
                        node.Tree = this; 
                    }
                    else
                    {
                        node.Parent = node.Parent.LeftChild; 
                        this.Add(node); 
                    }
                }
                else //Inserisce il nodo a destra
                {
                    if (node.Parent.RightChild == null)
                    {
                        node.Parent.RightChild = node; 
                        size++;
                        node.Tree = this; 
                    }
                    else
                    {
                        node.Parent = node.Parent.RightChild;
                        this.Add(node);
                    }
                }
            }
        }
                
        int Height (TreeNode root) // Restituisce l'altezza del'albero
        {
            if (root == null) return -1;

            int Hl = Height(Left(root));
            int Hr = Height(Right(root));
            if (Hl > Hr) return (1 + Hl);
            else return (1+Hr);
        }
               
        int NodeCounter (TreeNode root)
        {
            if (root == null) return (0);
            // Per ogni nodo visitato somma 1 alle chiamate ricorsive
            else return (1 + NodeCounter(Left(root)) + NodeCounter(Right(root)));
        }

        TreeNode Left(TreeNode root) // Restituisce il sottoalbero sinistro
        {
            if (root == null) return (null);
            else return (root.LeftChild);
        }

        TreeNode Right(TreeNode root) // Restituisce il sottoalbero destro
        {
            if (root == null) return (null);
            else return (root.RightChild);
        }
    }
}
cosa ne pensate? se il contanodi é corretto mi manca "solo" la routine che elenca i nodi livello per livello per esempio: tutti i bisnonni, tutti i nonni, tutti i genitori e tutta la generazione corrente.

L'ho implementata così...
Codice:
  int countNodeSameLevel(TreeNode root, int h) //// Restituisce il numero di nodi di un determinato livello h
        {

            if (root == null)
            {
                return 0;
            }
            if (h == 0)
            {
                return 1;
            }
            else
            {
                return countNodeSameLevel(root.LeftChild, h - 1) + countNodeSameLevel(root.RightChild, h - 1);
            }
        }

Ultima modifica di ideafissa : 01-03-2010 alle 19:16.
ideafissa è offline   Rispondi citando il messaggio o parte di esso
Old 03-03-2010, 00:42   #10
Badrepent
Junior Member
 
Iscritto dal: Apr 2008
Messaggi: 3
Ciao Daniele, sono Luca
allora ti posto la soluzione al problema che hai posto (testa tutto per controllare bene che funzioni, ho fatto delle semplici prove e non ho sviluppato usando tdd). Il codice che avevi postato utilizzava un albero binario di ricerca, per il tuo contesto secondo me non è adatto in quanto ad esempio il numero di figli potrebbe essere pari a 1,2,3,4 etc quindi ho creato un albero non binario non di ricerca ma semplicemente un albero con numero variabile di figli.
Ho utilizzato diverse stili nel codice, ovvero alcune funzionalità le ho implementate seguendo un approccio classico senza ricorrere a particolari funzionalità che offre il C#. Per il conteggio dei nodi ad esempio ho utilizzato un passaggio di una value type per riferimento (cosi vedi come la differenza rispetto a c/c++).
Per quanto riguarda la visità per livelli (visita in ampiezza) ho utilizzato la classica coda ed un iteratore che utilizza yield return per congelare la stato di esecuzione...
posto qui i vari files che compongono la console application di prova

Classe Genealogic Tree
Codice:
public class GenealogicTree
    {
     
        private TreeNode root {get;set;}

        public GenealogicTree(String ancestorName)
        {
            root = new TreeNode(ancestorName);
        }
        
        public Boolean addDescendant(String name, string parentName)
        {
            if (parentName.Equals(root.name))
                return root.addChild(name);
            else
                return addDescendant(name, parentName, root);                    
        }

        private Boolean addDescendant(string name, string parentName, TreeNode ancestor)
        {
            if (ancestor.name.Equals(parentName))
                return ancestor.addChild(name);

            int index = 0;
            Boolean found = false;
            while ( (index < ancestor.childs.Count) && (found == false) )
            {
                found = addDescendant(name, parentName, ancestor.childs[index]);
                index++;
            }
            return found;
        }

        private TreeNode findNode(String ancestorName, TreeNode current)
        {
            if (current.name.Equals(ancestorName, StringComparison.CurrentCultureIgnoreCase))
                return current;
            else
            {
                int i = 0;
                Boolean again = true;
                TreeNode subTree = null;
                while (again == true && i < current.childs.Count)
                {
                    subTree = findNode(ancestorName, current.childs[i]);
                    if (subTree != null)
                        again = false;
                    else
                        i++;
                }
                return subTree;
            }
        }

        public IEnumerator<TreeNode> printDescendants(String ancestorName)
        {
            TreeNode ancestor = findNode(ancestorName, root);
            Queue<TreeNode> breadthQueue = new Queue<TreeNode>();
            breadthQueue.Enqueue(ancestor);            
            while (breadthQueue.Count>0)
            {
                TreeNode actualNode = breadthQueue.Dequeue();
                foreach (TreeNode child in actualNode.childs)
                    breadthQueue.Enqueue(child);
                yield return actualNode;
            }            
        }

        public int countNode()
        {
            int count=0;
            if (root==null)            
                count=  0;  
            else
                countInternalNode(root, ref count);
            return count+1;
        }

        private void countInternalNode(TreeNode node, ref int count)
        {
            foreach (TreeNode n in node.childs)
            {
                count++;
                countInternalNode(n, ref count);
            }            
        }                
    }

Classe TreeNode
Codice:
  public class TreeNode 
    {
        public String name { get; set; }
        public List<TreeNode> childs { get; set; }

        public TreeNode(String name)
        {
            this.name = name;
            childs = new List<TreeNode>();
        }        

        public TreeNode getChild(int index)
        {
            if ((index < 0) || (index >= childs.Count))
                throw new Exception("error in retrieving child" + index.ToString());
            return childs[index];
        }

        public Boolean addChild(String childName)
        {
            childs.Add(new TreeNode(childName));
            return true;
        }

    }
Classe Console App

Codice:
    static void Main(string[] args)
        {
            GenealogicTree tree = new GenealogicTree("Luca");
            tree.addDescendant("Carlo", "Luca");
            tree.addDescendant("Cristina", "Luca");
            tree.addDescendant("Dario", "Luca");
            tree.addDescendant("Ema", "Carlo");
            tree.addDescendant("Fra", "Carlo");
            tree.addDescendant("Guido", "Carlo");
            tree.addDescendant("Emma", "Cristina");
            tree.addDescendant("Ingo", "Dario");
            tree.addDescendant("Lucia", "Dario");
            tree.addDescendant("Manu", "Fra");
            tree.addDescendant("Nico", "Fra");
            tree.addDescendant("Orazio", "Fra");
            tree.addDescendant("Paride", "Fra");
            tree.printDescendants("Carlo");
            Console.WriteLine("num nodi {0}", tree.countNode());
            IEnumerator<TreeNode> enumerator = tree.printDescendants("Carlo");
            while (enumerator.MoveNext())
                Console.WriteLine(enumerator.Current.name);
            Console.Read();
            
        }
Spero ti sia di aiuto, se ci fossero problemi postali pure qui
Luca
Badrepent è offline   Rispondi citando il messaggio o parte di esso
Old 03-03-2010, 10:54   #11
ideafissa
Member
 
Iscritto dal: Sep 2004
Messaggi: 113
Grazie per l'aiuto ora gli do un'occhiata
ideafissa è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Samsung Galaxy S25 Edge: il top di gamma ultrasottile e leggerissimo. La recensione Samsung Galaxy S25 Edge: il top di gamma ultraso...
HP Elitebook Ultra G1i 14 è il notebook compatto, potente e robusto HP Elitebook Ultra G1i 14 è il notebook c...
Microsoft Surface Pro 12 è il 2 in 1 più compatto e silenzioso Microsoft Surface Pro 12 è il 2 in 1 pi&u...
Recensione REDMAGIC Astra Gaming Tablet: che spettacolo di tablet! Recensione REDMAGIC Astra Gaming Tablet: che spe...
Dopo un mese, e 50 foto, cosa abbiamo capito della nuova Nintendo Switch 2 Dopo un mese, e 50 foto, cosa abbiamo capito del...
Electra ottiene altri 433 milioni di eur...
Cercate un hard disk esterno? Oggi Seaga...
Wi-Fi 8 sarà più affidabil...
Eccolo ancora, nuovo e non certo ricondi...
Thingiverse, stretta sulle armi 3D: perc...
DDR6 in dirittura d'arrivo: si punta su ...
Google Pixel 10 Pro Fold! Ecco tutti i d...
Sei pronto per il LEGO Game Boy? Ecco qu...
Google ha speso 14 miliardi in nuovi ser...
Primo semestre 2025, i veicoli elettrici...
Come va il principale produttore di semi...
Quando la sonda resta in magazzino: cosa...
Oggi grandi affari con i FRITZ!Repeater ...
Display nano-texture e più resist...
Apple Watch SE di seconda generazione? O...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 14:11.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v