Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Ispis duplikata iz niza

[es] :: .NET :: Ispis duplikata iz niza

[ Pregleda: 2666 | Odgovora: 9 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Shavgan
.NET Developer

Član broj: 169768
Poruke: 91
92.36.244.*



+1 Profil

icon Ispis duplikata iz niza15.11.2011. u 10:44 - pre 150 meseci
Problem je sljedeći. Potrebno je napraviti formu u Visual Studiu 2010 u kojoj će se ispisivati (listview ili combobox itd) duplikati tipa string liste i zbroj duplikata. (Npr. ako se unutar liste tipa string "dobardan" ponavlja 4 puta da ispise na sljedeci nacin: (dobardan: 4) Ja sam uradio tako da mi samo ispise duplikate ali ne znam kako da mi prikaze i broj ponavljanja u listi za dati string!!! hvala puno unaprijed



List<string> list = new List<string>();
list.Add("adnan");
list.Add("dado");
list.Add("mirza");
list.Add("mirza");
list.Add("adnan");
list.Add("adis");


List<string> novalist = list.FindAll(delegate(string i)
{

return list.FindAll(delegate(string j)
{

return j == i;

}).Count() > 1;

}).Distinct().ToList();
foreach (string value in novalist)
{
Console.WriteLine("Duplikati: {0}", value);

}


Output: adnan
mirza
 
Odgovor na temu

Dejan Carić
Oslo, Norway

Član broj: 230976
Poruke: 232
82.117.199.*

Sajt: www.dcaric.com


+26 Profil

icon Re: Ispis duplikata iz niza15.11.2011. u 11:16 - pre 150 meseci
Code:
var q = from x in list
        group x by x into g
        let count = g.Count()
        where count > 1
        orderby count descending
        select new {Value = g.Key, Count = count};

foreach (var x in q)
{
    Console.WriteLine("Value: " + x.Value + " Count: " + x.Count);
}

 
Odgovor na temu

Shavgan
.NET Developer

Član broj: 169768
Poruke: 91
92.36.244.*



+1 Profil

icon Re: Ispis duplikata iz niza15.11.2011. u 13:47 - pre 150 meseci
Nesto ovako :

new List<int>{1,1,1,2,2,3,4,5,6}
.ToLookup(k => k)
.Where(i => !i.Count().Equals(1))
.ToList().ForEach(i =>
Console.WriteLine("{0} duplikata se ponavlja {1} puta.", i.Key, i.Count())
);

Ali meni konkretno treba sljedeće. Ja sam listu dobio dinamički, tj pozivajući funkciju da mi čita imena dijelova koji čine jednu konstrukciju iz jednog CAD alata (SolidEdge-a) Ta imena sam prikazao pomoću listView controle. Unutar listview imam i imena dupliciranih dijelova,tj. prikazana su npr.dva,tri puta. Sad je potrebno iz te liste izvucem imena duplikata i pored imena da pise koliko puta se taj dio duplicirao. Prikazati se moze u jos jednom listview ili combobox-u koji je readonly. Mislim da sam uspio predociti moj problem...nadam se da ce bizi pomoci od strane forumasa...
 
Odgovor na temu

mmix
Miljan Mitrović
Profesorkin muz
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6041



+4631 Profil

icon Re: Ispis duplikata iz niza15.11.2011. u 13:56 - pre 150 meseci
nije ti bas efikasno to resenje, ono koje ti je Dejan dao je mnogo bolje.
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan, sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv… - Z.Đinđić
 
Odgovor na temu

sallle
Sasa Ninkovic
GTECH
Beograd

Član broj: 146
Poruke: 480
*.finsoft.co.yu.

ICQ: 20785904


+4 Profil

icon Re: Ispis duplikata iz niza15.11.2011. u 14:39 - pre 150 meseci
Ovaj tip problema se pojavljuje u ovim zajebanim softverskim firmama na testiranjima (fb,google, ms...), i prebrojavanje treba raditi koristeci hash tabelu.
U principu i ovaj linq iz prethodnih postova ispod haube verovatno radi slicno...

Code:

Dictonary<string,int> dict = new Dictionary<string,int>()
foreach (var rec in list)
{
if (dict.containsKey(rec))
   dict[rec]++;
else
   dict.insert(rec,1);
}
 
Odgovor na temu

Dejan Carić
Oslo, Norway

Član broj: 230976
Poruke: 232
82.117.199.*

Sajt: www.dcaric.com


+26 Profil

icon Re: Ispis duplikata iz niza15.11.2011. u 15:26 - pre 150 meseci
Dictionary jeste brži ali samo pod uslovom da rec nikada nije null.
S obzirom da je string referentni tip, tako nešto je ipak moguće i tu dict[rec]++; puca.

GroupBy je sporiji jer ima tu proveru ali zato sa njim možeš dohvatiti broj stringova koji su null.
 
Odgovor na temu

Boris B.
Ljubljana

Član broj: 213615
Poruke: 286
*.dynamic.t-2.net.



+14 Profil

icon Re: Ispis duplikata iz niza26.11.2011. u 00:10 - pre 150 meseci
Citat:
Dejan CarićDictionary jeste brži ali samo pod uslovom da rec nikada nije null.
S obzirom da je string referentni tip, tako nešto je ipak moguće i tu dict[rec]++; puca.

GroupBy je sporiji jer ima tu proveru ali zato sa njim možeš dohvatiti broj stringova koji su null.


Zanimljivo, ispada da je Dictionary implementacija oko 2x sporija od one tvoje implementacije sa čistim linq query-em:
Code (csharp):

        private void button1_Click(object sender, EventArgs e)
        {
            var wordlist = new[] { "lorem", "ipsum", "dolor", "sit", "amet", "null" };
            var rnd = new Random(42);
            var sample = new List<string>(10000);
            for (var i = 0; i < 10000; i++)
                sample.Add(wordlist[rnd.Next(wordlist.Count())]);

            var start = DateTime.Now.Ticks;
            for(var i = 0; i < 1000; i++)
            {
                var res = (from x in sample
                         group x by x into g
                         let count = g.Count()
                         where count > 1
                         orderby count descending
                         select new {Value = g.Key, Count = count}).ToList();
            }
            System.Diagnostics.Debug.Print(new TimeSpan(DateTime.Now.Ticks - start).ToString());
        }

        private void button2_Click(object sender, EventArgs e)
        {
            var wordlist = new[] { "lorem", "ipsum", "dolor", "sit", "amet", "null" };
            var rnd = new Random(42);
            var sample = new List<string>(10000);
            for (var i = 0; i < 10000; i++)
                sample.Add(wordlist[rnd.Next(wordlist.Count())]);

            var start = DateTime.Now.Ticks;
            for (var i = 0; i < 1000; i++)
            {
                var res = new Dictionary<string, int>();
                foreach (var s in sample)
                    if (res.ContainsKey(s))
                        res[s]++;
                    else
                        res.Add(s, 1);
            }
            System.Diagnostics.Debug.Print(new TimeSpan(DateTime.Now.Ticks - start).ToString());
        }
 


Rezultat (i7-930):
00:00:00.8290474 -- Linq group
00:00:01.3500773 -- Dictionary

Nema null vrednosti, da bi bilo "fer". Rezultat Dictionary implementacije još uključuje i rezultate sa jednim ponavljanjem, znači trebao bi i još jedan filter na kraju.


EDIT:
Ruku na srce Dictionary implementacija može da se malo bolje napiše, da se izbegne trodupli lookup, jer indekser++ u stvari radi set(get()+1) plus jedan za ContainsKey():
Code (csharp):

    int count;
    foreach (var s in sample)
        if (res.TryGetValue(s, out count))
            res[s] = count + 1;
        else
            res.Add(s, 1);
 

Ovo se izvršava za 00:00:00.9590548, što je dosta bolje mada još uvek sporije od linq implementacije.

[Ovu poruku je menjao Boris B. dana 26.11.2011. u 02:11 GMT+1]
if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
 
Odgovor na temu

sallle
Sasa Ninkovic
GTECH
Beograd

Član broj: 146
Poruke: 480
..106.109.adsl.dyn.beotel.net.

ICQ: 20785904


+4 Profil

icon Re: Ispis duplikata iz niza26.11.2011. u 03:02 - pre 150 meseci
Borise, sta kaze output za ovu varijantu?

Code:

var res = new Dictionary<string, Broj>();
                Broj b;
                foreach (var s in sample)
                    if (res.TryGetValue(s, out b))
                        b.val++;
                    else
                        res.Add(s, new Broj() { val = 1 });


Code:

public class Broj
    {
        public int val;
    }


 
Odgovor na temu

Boris B.
Ljubljana

Član broj: 213615
Poruke: 286
*.dynamic.t-2.net.



+14 Profil

icon Re: Ispis duplikata iz niza26.11.2011. u 11:06 - pre 150 meseci
Da, to je "dobitna kompbinacija", izbegnes double lookup sa referencom.

Sad se izvršava za 00:00:00.6042314. Kako bi još efikasno uključio i brojanje null-ova?



if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
 
Odgovor na temu

sallle
Sasa Ninkovic
GTECH
Beograd

Član broj: 146
Poruke: 480
..106.109.adsl.dyn.beotel.net.

ICQ: 20785904


+4 Profil

icon Re: Ispis duplikata iz niza26.11.2011. u 11:49 - pre 150 meseci

Code:

var res = new Dictionary<string, Broj>();
int nullCount=0;
                Broj b;
                foreach (var s in sample)
                {
                    if (s == null)
                    {
                        nullCount++;
                        continue;
                    }
                    if (res.TryGetValue(s, out b))
                        b.val++;
                    else
                        res.Add(s, new Broj() { val = 1 });
                  }


btw, ako u wordlist ubacis null, ovo ce jos brze da radi nego prethodna verzija bez provere null-a. (jer za nullove nece raditi lookup)
 
Odgovor na temu

[es] :: .NET :: Ispis duplikata iz niza

[ Pregleda: 2666 | Odgovora: 9 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.