1 / 1 / 0
Регистрация: 05.10.2011
Сообщений: 46
1

Интерфейс IEnumerable: вывести сначала чётные, потом нечётные элементы коллекции

10.07.2014, 16:04. Показов 4597. Ответов 23
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Работа с коллекциями, по заданию нужно вывести сначала все четные, затем все нечётные коллекции, часть кода приведенный ниже выводит все подряд

C#
1
2
3
4
5
6
7
8
9
10
11
12
int position = -1;
 
 public bool MoveNext()
    {
        position++;
        return (position < _people.Length);
    }
 
    public void Reset()
    {
        position = -1;
    }
Добавлено через 2 часа 18 минут
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
using System;
using System.Collections;
 
public class Person
{
    public Person(string fName, string lName)
    {
        this.firstName = fName;
        this.lastName = lName;
    }
 
    public string firstName;
    public string lastName;
}
 
public class People : IEnumerable
{
    private Person[] _people;
    public People(Person[] pArray)
    {
        _people = new Person[pArray.Length];
 
        for (int i = 0; i < pArray.Length; i++)
        {
            _people[i] = pArray[i];
        }
    }   IEnumerator IEnumerable.GetEnumerator()
    {
       return (IEnumerator) GetEnumerator();
    }
 
    public PeopleEnum GetEnumerator()
    {
        return new PeopleEnum(_people);
    }
}
 
public class PeopleEnum : IEnumerator
{
    public Person[] _people;
 
    
    int position = -1;
 
    public PeopleEnum(Person[] list)
    {
        _people = list;
    }
 
    public bool MoveNext()
    {
        position++;
        return (position < _people.Length);
    }
 
    public void Reset()
    {
        position = -1;
    }
 
    object IEnumerator.Current
    {
        get
        {
            return Current;
        }
    }
 
    public Person Current
    {
        get
        {
            try
            {
                return _people[position];
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
}
 
class App
{
    static void Main()
    {
        Person[] peopleArray = new Person[6]
        {
            new Person("бла", "бла"),
            new Person("бу", "бу"),
            new Person("аа", "аа"),
            new Person("фф", "фф"),
            new Person("ее", "ее"),
            new Person("ту", "ту"),
        };
 
        People peopleList = new People(peopleArray);
        foreach (Person p in peopleList)
            Console.WriteLine(p.firstName + " " + p.lastName);
 
    }
}
В результате я получаю:
бла бла
бу бу
аа аа
фф фф
ее ее
ту ту
т.к идет простой перебор
А надо:
бла бла
аа аа
ее ее
бу бу
фф фф
ту ту
циклами не получается, есть вариант использовать foreach, но не знаю как получить номер строки.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.07.2014, 16:04
Ответы с готовыми решениями:

Переписать все числа во второй массив так, чтобы сначала шли четные элементы, затем нули, потом нечетные элементы
Парни, нуждаюсь в ваших советах. Из одномерного целочисленного массива переписать все числа во...

Из массива переписать числа во второй массив так, чтобы сначала шли четные элементы, затем нули, потом нечетные элементы
Доброго времени суток! Помогите решить задание на с#: Из одномерного целочисленного массива...

Вывести сначала четные потом нечетные элементы массива
Задача на одномерный массив: Дан массив размера N. Вывести его сначала элементы четные потом...

Вывести на экран сначала четные элементы массива потом нечетные
Дан массив целых чисел. Вывести на экран сначало четные элементы массива потом не четные

23
Эксперт .NET
5545 / 4308 / 1218
Регистрация: 12.10.2013
Сообщений: 12,352
Записей в блоге: 2
10.07.2014, 16:21 2
Богдан18, вот честно сказать я хз что вы хотите получить и к чему тут IEnumerable... У вас класс Person, потом создаете коллекцию из этих этих объектов. А дальше? Мне вообще непонятна логика, как должны выводиться эти элементы, логика вывода... Может проще использовать обычный LINQ, и не заниматься извращениями?
1
1 / 1 / 0
Регистрация: 05.10.2011
Сообщений: 46
10.07.2014, 17:52  [ТС] 3
Лаба такая у меня, я давно уже по другому сделал, но препад не принял, вот сказал переделать!
0
123 / 123 / 72
Регистрация: 11.05.2014
Сообщений: 331
10.07.2014, 18:01 4
В лоб можно так:
В класс People добавьте:

C#
1
2
3
4
5
6
    public Person this[int index] {
        get { return _people[index]; }
        set { _people[index] = value; }
    }
 
    public int Count { get { return _people.Length; } }
Ну а в Main вместо foreach как-то так:

C#
1
2
3
4
5
6
7
        for (int i = 0; i < peopleList.Count; i+=2) {
            Console.WriteLine(peopleList[i].firstName + " " + peopleList[i].lastName);            
        }
 
        for (int i = 1; i <= peopleList.Count; i += 2) {
            Console.WriteLine(peopleList[i].firstName + " " + peopleList[i].lastName);
        }
Первое, что пришло в голову -_-
0
1 / 1 / 0
Регистрация: 05.10.2011
Сообщений: 46
10.07.2014, 18:09  [ТС] 5
Спасибо, но мне по заданию нужно через foreach выводить коллекцию.
Не знаете ли Вы, как в foreach , получить номер выводимой строки?
0
123 / 123 / 72
Регистрация: 11.05.2014
Сообщений: 331
10.07.2014, 18:27 6
Можно написать новый перечислитель в классе Person и использовать его:

C#
1
2
3
4
5
6
7
8
9
10
11
    public IEnumerable CustomEnumerator {
        get {
            for (int i = 0; i < _people.Length; i += 2) {
                yield return _people[i];
            }
 
            for (int i = 1; i <= _people.Length; i += 2) {
                yield return _people[i];
            }
        }
    }
Цикл тогда такой будет:

C#
1
2
     foreach (Person p in peopleList.CustomEnumerator)
            Console.WriteLine(p.firstName + " " + p.lastName);

Не по теме:

Подозреваю, что получу тонну кирпичей в свой адрес за такое творчество)

0
Эксперт .NET
5545 / 4308 / 1218
Регистрация: 12.10.2013
Сообщений: 12,352
Записей в блоге: 2
10.07.2014, 19:05 7
Detect, ну почему... Вот немного подправленный вариант. По-моему, вполне неплохо работает, и выдает то что требуется ТС...
Класс Person
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class Person
    {
        private string firstName;
        private string lastName;
        public Person(string fName, string lName)
        {
            firstName = fName;
            lastName = lName;
        }
        public string FirstName
        {
            get { return firstName; }
        }
        public string LastName
        {
            get { return lastName; }
        }
        public override string ToString()
        {
            return string.Format("First name: {0}, Last name: {1}",
                                 FirstName, LastName);
        }
    }
}
Класс People
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class People
    {
        private Person[] people;
 
        public People(Person[] pArr)
        {
            people = pArr;
        }
        public IEnumerable<Person> GetCustomEnumerator(int pos)
        {
            if (pos != 0 && pos != 1)
                throw new ArgumentException("Argument cycle error!");
 
            for (int i = pos; i < people.Length; i += 2)
            {
                yield return people[i];
            }
        }
    }
}
Собственно Main()
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Person[] peopleArray = new Person[6]
        {
            new Person("бла", "бла"),
            new Person("бу", "бу"),
            new Person("аа", "аа"),
            new Person("фф", "фф"),
            new Person("ее", "ее"),
            new Person("ту", "ту"),
        };
 
            People peopleList = new People(peopleArray);
            foreach (Person p in peopleList.GetCustomEnumerator(0))
                Console.WriteLine(p.ToString());
 
            Console.WriteLine();
 
            foreach (Person p in peopleList.GetCustomEnumerator(1))
                Console.WriteLine(p.ToString());
 
            Console.ReadLine();
        }
    }
}
PS. Кстати, ТС, за такое издевательство над инкапсуляцией на месте вашего препода я бы и в остальном правильно выполненную работу не принял. Зачем делать поля public?
0
1 / 1 / 0
Регистрация: 05.10.2011
Сообщений: 46
13.07.2014, 11:56  [ТС] 8
Спасибо, но и этот ответ забраковал, сказав, что foreach должен быть один! И вывод должен быть реализован с помощью
MoveNext(), Reset() и Current.
0
Master of Orion
Эксперт .NET
6100 / 4956 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
13.07.2014, 12:23 9
окей, вот MoveNext, удачи
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using System;
using System.Collections.Generic;
 
namespace ConsoleApplication108
{
    public class Person
    {
        public Person(string fName, string lName)
        {
            FirstName = fName;
            LastName = lName;
        }
 
        public string FirstName { get; set; }
 
        public string LastName { get; set; }
 
        public override string ToString()
        {
            return string.Format("First name: {0}, Last name: {1}",
                                 FirstName, LastName);
        }
    }
 
    public static class PersonExtender
    {
        public static IEnumerator<T> GetOddEvenEnumerator<T>(this IList<T> enumerable)
        {
            for (int i = 0; i < enumerable.Count; i += 2)
            {
                yield return enumerable[i];
            }
            for (int i = 1; i < enumerable.Count; i += 2)
            {
                yield return enumerable[i];
            }
        }
    }
 
    class Program
    {
        private static void Main(string[] args)
        {
            Person[] peopleArray =
            {
                new Person("бла", "бла"),
                new Person("бу", "бу"),
                new Person("аа", "аа"),
                new Person("фф", "фф"),
                new Person("ее", "ее"),
                new Person("ту", "ту"),
            };
 
            var enumerator = peopleArray.GetOddEvenEnumerator();
            while (enumerator.MoveNext())
            {
                Console.WriteLine(enumerator.Current);
            }
 
        }
    }
}
0
1 / 1 / 0
Регистрация: 05.10.2011
Сообщений: 46
13.07.2014, 12:43  [ТС] 10
foreach нет(
Извините, но не покатит(
я пробовал так
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public bool MoveNext()
{
if (position < _people.Length)
{
position += 2;
return true;
}
else
 
{
position = -1;
if (position < _people.Length)
{
position += 2;
return true;
}
else return false;
}
 
 
}
Сделал отладку, сначала оно бегает по первому if-у, как и надо, когда (position >_people.Length), выполняет else, 1 раз , а потом снова заходит в первый if и так циклит.



Ещё пробовал добавлять условие чётности/нечетности как-то не корректно работает и " выходит за границы массива"
0
Master of Orion
Эксперт .NET
6100 / 4956 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
13.07.2014, 13:32 11
Богдан18, окей:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using System;
using System.Collections;
using System.Collections.Generic;
 
namespace ConsoleApplication108
{
    public class Person
    {
        public Person(string fName, string lName)
        {
            FirstName = fName;
            LastName = lName;
        }
 
        public string FirstName { get; set; }
 
        public string LastName { get; set; }
 
        public override string ToString()
        {
            return string.Format("First name: {0}, Last name: {1}",
                                 FirstName, LastName);
        }
    }
 
    public static class PersonExtender
    {
        public static IEnumerator<T> GetOddEvenEnumerator<T>(this IList<T> enumerable)
        {
            return new EvenOddEnumerator<T>(enumerable);
        }
    }
 
    public class EvenOddEnumerator<T> : IEnumerator<T>
    {
        private readonly IEnumerator<T> _enumerable;
        private Queue<T> _odds = new Queue<T>();
 
        public EvenOddEnumerator(IEnumerable<T> enumerable)
        {
            _enumerable = enumerable.GetEnumerator();
        }
 
        public void Dispose()
        {
            _odds = null;
        }
 
        public bool MoveNext()
        {
            if (_odds == null)
                throw new ObjectDisposedException(ToString());
            if (!_enumerable.MoveNext())
            {
                if (_odds.Count == 0)
                    return false;
                Current = _odds.Dequeue();
                return true;
            }
            Current = _enumerable.Current;
            if (_enumerable.MoveNext())
            {
                _odds.Enqueue(_enumerable.Current);
            }
            return true;
        }
 
        public void Reset()
        {
            _odds = new Queue<T>();
        }
 
        public T Current { get; private set; }
 
        object IEnumerator.Current
        {
            get
            {
                return Current;
            }
        }
    }
 
    class Program
    {
        private static void Main(string[] args)
        {
            Person[] peopleArray =
            {
                new Person("бла", "бла"),
                new Person("бу", "бу"),
                new Person("аа", "аа"),
                new Person("фф", "фф"),
                new Person("ее", "ее"),
                new Person("ту", "ту"),
            };
 
            var enumerator = peopleArray.GetOddEvenEnumerator();
            while (enumerator.MoveNext())
            {
                Console.WriteLine(enumerator.Current);
            }
 
        }
    }
}
надеюсь, разберетесь.
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
13.07.2014, 13:34 12
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using System;
using System.Collections;
 
public class Person
{
    public Person(string fName, string lName)
    {
        this.firstName = fName;
        this.lastName = lName;
    }
 
    public string firstName;
    public string lastName;
}
 
public class People : IEnumerable
{
    private Person[] _people;
    
    public People(Person[] pArray)
    {
        _people = new Person[pArray.Length];
 
        for (int i = 0; i < pArray.Length; i++)
        {
            _people[i] = pArray[i];
        }   
    }   
    
    IEnumerator IEnumerable.GetEnumerator()
    {
       return GetEnumerator();
    }
 
    public IEnumerator GetEnumerator()
    {
        return new PeopleEnum(_people);
    }
 
    struct PeopleEnum : IEnumerator
    {
        private const int Delta = 2;
        
        private Person[] people;
     
        private int position;
        
        private bool isEvenFinished;
     
        public PeopleEnum(Person[] list)
        {
            people = list;
            position = -Delta;
            isEvenFinished = false;
        }
     
        public bool MoveNext()
        {
            position += Delta;
            
            if (position == people.Length)
            {
                if (!isEvenFinished)
                {
                    position = 1;
                    isEvenFinished = true;
                }
                
            }
            
            return position < people.Length;
        }
     
        public void Reset()
        {
            position = -Delta;
        }
     
        object IEnumerator.Current
        {
            get
            {
                return Current;
            }
        }
     
        public Person Current
        {
            get
            {
                try
                {
                    return people[position];
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }
    }
}
    
public class App
{
    public static void Main()
    {
        Person[] peopleArray = new Person[6]
        {
            new Person("бла", "бла"),
            new Person("бу", "бу"),
            new Person("аа", "аа"),
            new Person("фф", "фф"),
            new Person("ее", "ее"),
            new Person("ту", "ту"),
        };
 
        People peopleList = new People(peopleArray);
        foreach (Person p in peopleList)
            Console.WriteLine(p.firstName + " " + p.lastName);
 
    }
}
0
147 / 73 / 17
Регистрация: 31.05.2014
Сообщений: 215
13.07.2014, 13:35 13
Богдан18, вот ещё один способ
C#
1
2
3
4
5
6
7
8
 int i = 0;
            foreach (Person p in peopleList)
            {
                i++;
                if (i % 2 == 1) Console.CursorTop = i / 2;
                else Console.CursorTop = peopleList.GetLenght() / 2 + peopleList.GetLenght() % 2 + i / 2 - 1;
                Console.WriteLine(p.firstName + " " + p.lastName);
            }
Только нужно добавить
C#
1
2
3
4
public int GetLenght()
    {
        return _people.Length;
    }
в класс people
0
Master of Orion
Эксперт .NET
6100 / 4956 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
13.07.2014, 13:58 14
Jupiter, а вот имплементировать IEnumrator - плохо А уж сокращать до enum вообще преступление

Не по теме:

есть вопрос по С++, в ЛС Название: spy.gif
Просмотров: 255

Размер: 1.3 Кб

0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
13.07.2014, 14:02 15
Цитата Сообщение от Psilon Посмотреть сообщение
а вот имплементировать IEnumrator - плохо
никогда раньше не делал, а чем плохо?

Цитата Сообщение от Psilon Посмотреть сообщение
А уж сокращать до enum вообще преступление
да скопипастил у ТС
0
Master of Orion
Эксперт .NET
6100 / 4956 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
13.07.2014, 14:09 16
Jupiter, с genericами потом проблемы. Большинство методов принимают IEnumerator<T>, они не поймут IEnumerator. .Net 2.0 уже 10 лет шагает по планете. Пора уже забыть про non-generic types
0
1 / 1 / 0
Регистрация: 05.10.2011
Сообщений: 46
13.07.2014, 14:11  [ТС] 17
А если в ListBox выводить?
C#
1
2
3
4
5
6
7
8
int i = 0;
            foreach (Person p in peopleList)
            {
                i++;
                if (i % 2 == 1) Console.CursorTop = i / 2;
                else Console.CursorTop = peopleList.GetLenght() / 2 + peopleList.GetLenght() % 2 + i / 2 - 1;
                Console.WriteLine(p.firstName + " " + p.lastName);
            }
0
Jupiter
13.07.2014, 14:13
  #18

Не по теме:

Цитата Сообщение от Psilon Посмотреть сообщение
Пора уже забыть про non-generic types
а, ну про это я в курсе, влом было дописывать generic реализацию)

0
Psilon
13.07.2014, 14:15
  #19

Не по теме:

Jupiter, ну и да, учитывая настойчисоть преподавателя, наверняка требуется итератор по IEnumerable, без индексных доступов :) Хотя кто его знает, конечно...

0
147 / 73 / 17
Регистрация: 31.05.2014
Сообщений: 215
13.07.2014, 14:21 20
C#
1
2
3
4
5
6
7
8
9
int i = 0;
            foreach (Person p in peopleList)
            {
                i++;
                int a =0;
                if (i % 2 == 1) a = i / 2;
                else a = peopleList.GetLenght() / 2 + peopleList.GetLenght() % 2 + i / 2 - 1;
                listBox1.Items.Insert(a, p.firstName + " " + p.lastName);
            }
Но это по большей мере просто хитрость - строки выводятся не друг за другом. Но задачу это решает
0
13.07.2014, 14:21
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.07.2014, 14:21
Помогаю со студенческими работами здесь

Вывести на экран сначала четные элементы массива, потом нечетные
2. Дан массив целых чисел. Вывести на экран сначала четные элементы массива, потом нечетные. S9...

Переписать в новый массив сначала нечетные, потом четные элементы.
помогите пожалуйста!! из массива JJ(100) в массив NN(100) перенести числа(элементы массива)...

Отсортировать массив, поставив сначала чётные элементы, а потом нечётные
Люди добрые помогите пожалуйста! мне нужно заполнить двумерный массив А случайными целыми числами...

Из массива вывести сначала нечетные числа, а потом четные
Как с массива Arr сначала вывести непарные числа ,а потом парные ?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru