Novo

Forum kao aplikacija na telefonu

Dodajte forum na početni ekran i koristite ga kao aplikaciju, sa menijem na dnu ekrana.

  • 9 odgovora
  • 4.336 pregleda

Najnovija ↓

Ispis duplikata iz niza 15.11.2011. u 11:44 · pre 182 meseca #1
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
Re: Ispis duplikata iz niza 15.11.2011. u 12:16 · pre 182 meseca #2
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);
}
Potpis
gramatika srpskog jezika
testovi iz srpskog jezika
jezičke nedoumice
Sviđa mi se1
Re: Ispis duplikata iz niza 15.11.2011. u 14:47 · pre 182 meseca #3
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...
Re: Ispis duplikata iz niza 15.11.2011. u 14:56 · pre 182 meseca #4
nije ti bas efikasno to resenje, ono koje ti je Dejan dao je mnogo bolje.
Potpis
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ć
Re: Ispis duplikata iz niza 15.11.2011. u 15:39 · pre 182 meseca #5
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);
}
Re: Ispis duplikata iz niza 15.11.2011. u 16:26 · pre 182 meseca #6
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.
Potpis
gramatika srpskog jezika
testovi iz srpskog jezika
jezičke nedoumice
Re: Ispis duplikata iz niza 26.11.2011. u 01:10 · pre 181 mesec
izmenjeno 1 put, poslednji put Boris B. 26.11.2011. u 02:11
  1. Boris B.26.11.2011. u 02:11zapis iz teksta poruke
#7
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.
Potpis
if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
Re: Ispis duplikata iz niza 26.11.2011. u 04:02 · pre 181 mesec #8
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;
    }


Sviđa mi se1
Re: Ispis duplikata iz niza 26.11.2011. u 12:06 · pre 181 mesec #9
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?


Potpis
if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
Re: Ispis duplikata iz niza 26.11.2011. u 12:49 · pre 181 mesec #10

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)
Prijavite se da biste odgovorili u ovoj temi.PrijavaRegistracija

Premeštanje teme