Loading...

Във форума е въведено ограничение, което позволява на потребителите единствено да разглеждат публикуваните въпроси.

Elena123456 avatar Elena123456 235 Точки

Print all unique elements in the array/list

Здравейте, днес попаднах на следната задача:

Print all unique elements in an array.

input:

1 2 3 4 5 5 5 6

output:

1 2 3 4 6

 

Запознах се с Distinct(), но с него принтирам само това "1 2 3 4 5 6". Има ли някакъв друг подобен метод, с които да кажа, че искам числата да се запишат в нов лист, но само ако не се повтарят, потретват и пр. в първоначалния лист? И разбира се кода да е разбираем за човек, който е на ниво Fundamental, защото всички решения, които прегледах досега в stackoverflow  бяха напълно неразбираеми. :)

Все пак мисля, че успях да измисля някакво решение само с Destinct плюс още един допълнителен for цикъл. Понеже нямам Judge за тази задача не съм сигурна дали не би се счупила програмата  с някой инпут. И вече установих, че при инпут 1 1 2 2 6, принтирам 2 6, вместо само 6.

using System;
using System.Collections.Generic;
using System.Linq;


namespace W3resourceArrayExe
{
    class MainClass
    {
        public static void Main(string[] args)
        {

            Console.Write("Input the number of elements to be stored in the first array: ");
            int input = int.Parse(Console.ReadLine());
            Console.WriteLine($"Input {input} elements in the array:");
            var firstList = new List<string>();

            for (int i = 0; i < input; i++)
            {

                Console.Write($"element-{i} : ");
                string num = Console.ReadLine();
                firstList.Add(num);
             }

            var newListDestinct = firstList.Distinct().ToList();
            for (int i = 0; i < newListDestinct.Count; i++)
            {
                int counter = -1;

                for (int k = 0; k < firstList.Count; k++)
                {
                    if (newListDestinct[i] == firstList[k])
                    {
                        counter++;
                    }
                    if (counter > 0)
                    {
                        newListDestinct.RemoveAt(i);
                        break;

                    }
                }
            }

            Console.WriteLine(string.Join(" ",newListDestinct));
        }
    }
}
 

 

Тагове:
0
Fundamentals Module 12/09/2020 01:52:23
krum_43 avatar krum_43 750 Точки

Ето едно кратко решение и от мен:

 

 

using System;
using System.Collections.Generic;
using System.Linq;

namespace Unicueelements
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = Console.ReadLine();
            List<int> inputList = input.Split().Select(int.Parse).ToList();
            List<int> newList = new List<int>();
            newList.Add(inputList[0]);
            for (int i = 1; i <inputList.Count;i++)
            {
                if(!newList.Contains(inputList[i]))
                {
                    newList.Add(inputList[i]);
                }
            }
            Console.WriteLine(String.Join(" ",newList));
        }
    }
}
 

1
14/09/2020 15:41:53
Elena123456 avatar Elena123456 235 Точки

Здравей @krum_43,

благодаря за включването. :)

Може би аз не съм задала достатъчно ясно условието.

При инпут: "1 1 1 2 3 4" аз искам само 2 3 4, т.е ако даден елемент от първоначалния лист се повтаря, потретва и пр. аз не искам да го принтирам във втория лист, защото той не е уникален по условие.

Случайно все още написания с молив лист А4 с инпутите и аутпутите на тази задача стой на бюрото ми. :)

инпут-----аутпут

1 1 1 2 3 4--- 2 3 4

2 3 4 1 1 1--- 2 3 4

2 3 1 1 1 4---- 2 3 4

2 1 3 1 1 4---- 2 3 4

1 2 1 1 3 4---- 2 3 4

2 1 1 3 1 4----- 2 3 4

2 1 1 3 4 1---- 2 3 4

1 1 1 2 2 2 3 4--- 3 4

1 1 1 3 4 2 2 2---- 3 4

3 4 1 1 1 2 2 2---- 3 4

3 1 1 1 2 2 4 2---- 3 4

3 1 1 1 2 2 2 4---- 3 4

1 1 1 2 2 2 3 4---- 3 4

1 1 2 3 2 4 1 1---- 3 4

 

Здравей @Drakojan,

да, при повторно тестване разбрах, че не връщам for цикъла от 0. И преди няколко дена коригирах кода си (втория ми пост) и работи коректно, поне с въпросните инпути. Но благодаря за забележката, тъкмо вече се надявам,че ще го имам предвид още преди тестването. :)

 

Поздрави!

 

 

 

0
14/09/2020 22:17:32
krum_43 avatar krum_43 750 Точки

Да,така е.

Забелязах грешката още вчера,но ме домързя да я корегирам.

Ето ти един код,който принтира само уникалните елементи:

https://pastebin.com/tiGcXTKw

1
15/09/2020 10:06:31
nickwork avatar nickwork 657 Точки

Като вариант може и така :)

static void Main( )
        {
            List<int> numbers = Console.ReadLine().Split().Select(int.Parse)
                .GroupBy(x => x)
                .Where(x => x.Count() == 1)
                .Select(x => x.Key)
                .ToList();

            Console.WriteLine(string.Join(" ", numbers));
        }

2
krum_43 avatar krum_43 750 Точки

Hello nickwork,

Твоите решения както обикновено са най-кратки и интересни.

Би ли пояснил защо ти е нужен този ред от кода ти,при условие че става въпрос за елементи на списък?

Select(x => x.Key)   ?!?

2
15/09/2020 12:01:09
nickwork avatar nickwork 657 Точки

Привет, това го правя за да взема само ключа на групата...groupby групира всички еднакви елементи в групи, като всяка група има ключ и елементи (все едно keyvaluepair)...използвам селект за да взема само ключа на групата, която отговаря на условието, което съм задал в where клаузата...ако не използвам селект колекцията ще остане под формата на групи и ще трябва да мисля други магии за да отпечатам само ключевете им (в случая селекта е идеален за тази цел, без него мисля, че ще се получи все едно лист от масиви ако след where веднага извикаш to list)...

List<int> numbers = Console.ReadLine().Split().Select(int.Parse)
                .GroupBy(x => x) // групира всички еднакви елементи в групи
                .Where(x => x.Count() == 1) // филтрира да останат групите, където броят на елементите в тях е равен на 1 (ако е повече от 1 значи не са уникални...) 
                .Select(x => x.Key) // взима само ключа на групата (самите елементи вече не са ни нужни)
                .ToList(); // прави лист от уникалните ключове

2
Elena123456 avatar Elena123456 235 Точки

Благодаря Ви за двете решение! :)

Ако нямате нищо против, пак ще изкоментирам най-краткото решение, че да съм сигурна, че не пропускам нещо.

Ако имаме масива 2 3 2 3 4 5 8

 .GroupBy(x => x) -- ще групира елементите в няколко масива с едно и също число , т.е "2 2", "3 3", "4", "5" ,"8" или са групирани, но са си в един и същи масив?

.Where(x => x.Count() == 1) -- ще вземе само тези с един елемент "4", "5", "8";

  .Select(x => x.Key) -- ще махне елементите от масивите, които са заделени за тях и ще направи възможно принтирането им самостоятелно?

Каква е разликата между "ключ" и "елементи"? Пазят се в отделни памети ли-едното като масив, а другото като прост тип? Защо когато се опитам да изтрия ".Select(x => x.Key) " от целия код, изобщо кода не работи?

0
nickwork avatar nickwork 657 Точки

Структурата на GroupBy е <TKey,TElement>. , като TElement представлява колекция от елементи. Тази структура доста прилича на речник, в случая бихме използвали  Dictionary<int, List<int>>. Ако имаме масива 2 3 2 3 4 5 8, с GroupBy ще получим 5 различни групи с ключове (2, 3, 4, 5, 8), като във всяка група (под всеки ключ) ще бъдат записани като елемнти :

2: [ 2, 2 ] 

3: [ 3, 3 ] 

4: [ 4 ]

5: [ 5 ]

8: [ 8 ]

Най добре разгледай в дебъг режим как изглежда тази структура и смятам, че ще ти стане ясно...даже добави още числа:

IEnumerable<IGrouping<int, int>> numbers = new int[] { 2, 3, 2, 3, 4, 5, 8 }
                .GroupBy(x => x);

 

.Where филтрира там където елементите под даден ключ са равни на 1..

За разликата между "ключ" и "елементи"...всеки ключ отговаря за определени елемнти...но по добре прегледай лекцията за... не се сещам как беше точното наименование в курса... нещо от рода речници, dictionary , асоциативни масиви.. и 3те наименования означават едно и също нещо...намери тази лекция..

И на края тези типове данни са рефентни, не се печатат без селект, защото без него се получава нещо като матрица.. като аналог все едно имаш int[] test = new int[] {1,2,3,4,5}; и викаш Console.WriteLine(test); което няма как да стане. 

...Предполагам, че в момента караш фундаменталс модула, ако да, и да не успееш да разбереш как точно се случва това преобразуване не се притеснявай, на този етап е много по важно да се научиш да решаваш поставените задачи с прости фор цикли, а не с готова функционалност, като тази предоставена ни от .Linq... успех :)

1
krum_43 avatar krum_43 750 Точки

Да,ясно.

0
Elena123456 avatar Elena123456 235 Точки

Здравейте  @nickwork,

вашето най-подробно обяснение предварително ми разпали голям интерес към асоциативните масиви, които ще са и следващата ми лекция във Фундаментал модула.

Мисля, че вашето кратко решение с използването на Linq вече ми се изясни.  Благодаря за отделеното време!

Поздрави!

0
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.