5 / 5 / 4
Регистрация: 11.10.2014
Сообщений: 57
1

Jugged (ступенчатые) массивы: Вместо двух циклов for использовать один foreach

11.10.2014, 14:49. Показов 2400. Ответов 15
Метки нет (Все метки)

Приветствую.
В одном из курсов по программированию на C# есть тема про ступенчатые массивы. В качестве дополнительного задания к уроку предлагается изменить программу, вместо двух циклов for использовать один foreach...
Я всю голову сломал, как это можно сделать без применения SelectMany, т.к. это только 4 урок и данный метод не изучался.
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
class Program
    class Program
    {
        static void Print(int[][] a)
        {
            for (int i = 0; i < a.Length; i++)
            {
                for (int j = 0; j < a[i].Length; j++)
                {
                    Console.Write("{0} ", a[i][j]);
                }
                Console.WriteLine();
            }
        }
        static void Input(out int[][] a)
        {
            Console.Write("n= ");
            int n = int.Parse(Console.ReadLine());
            a = new int[n][];
            for (int i = 0; i < a.Length; i++)
            {
                Console.Write("введите количество элементов в {0} строке: ", i);
                int j = int.Parse(Console.ReadLine());
                a[i] = new int[j];
                for (j = 0; j < a[i].Length; j++)
                {
                    Console.Write("a[{0}][{1}]= ", i, j);
                    a[i][j] = int.Parse(Console.ReadLine());
                }
            }
        }
        static void Change(int[][] a)
        {
            for (int i = 0; i < a.Length; i++)
            {
                Array.Sort(a[i]);
            }
        }
        static void Main()
        {
            int[][] a;
            Input(out a);
            Console.WriteLine("Исходный массив:");
            Print(a);
            Change(a);
            Console.WriteLine("Измененный массив:");
            Print(a);
        }
    }    
}
Вопрос звучал так:
1. Подумайте, можно ли в методе Print вместо вложенных циклов for использовать один
цикл foreach. Как в этом случае массив будет выводиться на экран?
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.10.2014, 14:49
Ответы с готовыми решениями:

Как использовать один запрос вместо двух?
В CMS есть различные типы внутренних объектов. У каждого объекта есть основные поля, общие для...

Использовать один блок try{} вместо двух, сохраняя производительность
LeniumSoft, а как бы вы переработали вот этот метод? Как видите, тут я кучу блоков try{} тоже...

Связанный список - использовать в функции один указатель вместо двух
Возможно ли использовать в этой функции один указатель вместо двух (*cur и *prev) ? #include...

Создание функции вместо двух циклов
Привет,помогите грамотно оформить код. У меня в программе есть два одинаковых цикла,но мне...

15
202 / 171 / 67
Регистрация: 04.10.2014
Сообщений: 839
11.10.2014, 15:21 2
что то типа
C#
1
foreach (int [] b in a) {}
0
Заблокирован
11.10.2014, 15:35 3
CSharp_user, нельзя, все равно надо два foreach писать
Но в обычных двумерных массивах можно заменить два for на 1 foreach:
C#
1
2
3
4
5
6
7
8
9
10
            int n = 3, m = 2;
            int[,] q = new int[n, m];
            Random rand = new Random();
            for (int i = 0; i < 3; i++)
                for (int j = 0; j < 2; j++)
                {
                    q[i, j] = rand.Next(0, 11);
                }
            foreach (var x in q)
                Console.Write("{0}\t", x);
Код
3       10      6       0       6       0       Для продолжения нажмите любую кл
авишу . . .
1
202 / 171 / 67
Регистрация: 04.10.2014
Сообщений: 839
11.10.2014, 15:39 4
C#
1
2
3
4
5
6
7
8
        int r = 0;
        int c = 0;
        foreach (int[] b in a) 
        {
            Console.Write("{0} ", a[r][c]);
            r++; c++;
 
        }
выводит, но не весь массив, а только элементы с перекрестными индексами))
0
5 / 5 / 4
Регистрация: 11.10.2014
Сообщений: 57
11.10.2014, 16:48  [ТС] 5
Значит ответ "НЕТ".
Тогда почему вопрос задан именно так?
Подумайте, можно ли в методе Print вместо вложенных циклов for использовать один
цикл foreach. Как в этом случае массив будет выводиться на экран?
Значит все же можно? Например в одну строку без пробелов.
0
202 / 171 / 67
Регистрация: 04.10.2014
Сообщений: 839
11.10.2014, 16:54 6
CSharp_user, слыхал о вопросах с подвохом? так вот это он и есть)

Добавлено через 4 минуты
CSharp_user, можно обдурить препода) кароче
C#
1
2
3
4
5
6
7
8
9
10
11
        int c = 0;
        foreach (int[] b in a)
        {
            while (c < b.Length)
            {
                Console.Write("{0} ", b[c]);
                c++;
            }
            c = 0;
            Console.WriteLine();
        }
Добавлено через 45 секунд
тут ведь один foreach, а про while ни слова
2
5 / 5 / 4
Регистрация: 11.10.2014
Сообщений: 57
11.10.2014, 17:07  [ТС] 7
Цитата Сообщение от meksik Посмотреть сообщение
слыхал о вопросах с подвохом? так вот это он и есть)
Цитата Сообщение от meksik Посмотреть сообщение
можно обдурить препода) кароче
Да это интернет-курсы. Был бы препод, спросил бы у него.
Ну ладно. Если это действительно вопрос с подвохом, то хрен с ним. Хотя раньше подобных подвохов не было. Можно было ответить на поставленный вопрос.

Добавлено через 9 минут
В общем единственный вариант, который удовлетворяет поставленному вопросу - это использование SelectMany:
C#
1
2
3
4
5
6
7
static void Print(int[][] a) 
        {
            foreach (int n in a.SelectMany(array => array))
            {
                Console.WriteLine(n);
            }
        }
При этом вывод будет в один столбец (если использовать WriteLine).
0
870 / 720 / 304
Регистрация: 15.04.2013
Сообщений: 2,047
Записей в блоге: 5
11.10.2014, 17:16 8
Лучший ответ Сообщение было отмечено CSharp_user как решение

Решение

CSharp_user,
Не единственный, можно еще так выводить, вывод точно такой же как и с двумя for
C#
1
2
3
4
5
6
7
static void Print(int[][] a)
    {
        foreach (var arr in a)
        {
            Console.WriteLine(String.Join(" ", arr));
        }
    }
2
202 / 171 / 67
Регистрация: 04.10.2014
Сообщений: 839
11.10.2014, 17:17 9
XRoy, и вправду работает о_О вот ведь мозг у человека
0
5 / 5 / 4
Регистрация: 11.10.2014
Сообщений: 57
11.10.2014, 17:43  [ТС] 10
Цитата Сообщение от XRoy Посмотреть сообщение
Не единственный, можно еще так выводить, вывод точно такой же как и с двумя for
Да, этот способ более изящный. Хотя я не понимаю, как я должен был "подумать", если в уроках ранее не было изучения String.Join()...
0
870 / 720 / 304
Регистрация: 15.04.2013
Сообщений: 2,047
Записей в блоге: 5
11.10.2014, 21:52 11
CSharp_user,
Задание ведь дополнительное, они обычно выходят за рамки изучаемого материала.
0
550 / 318 / 138
Регистрация: 08.02.2013
Сообщений: 609
11.10.2014, 22:18 12
можно еще как-то так, с object[] не получилось
C#
1
2
3
4
5
6
7
8
9
10
11
12
static void Print1(Array a)
{
    foreach (var x in a)
    {
        if (x.GetType().IsArray)
        {
            Print1((Array)x);
            Console.WriteLine();
        }
        else Console.Write("{0,5}", x);
    }
}
2
5 / 5 / 4
Регистрация: 11.10.2014
Сообщений: 57
13.10.2014, 11:09  [ТС] 13
Интересный подход с рекурсией, только я вообще не понял, как работают этот метод.
C#
1
if (x.GetType().IsArray)
ЕСЛИ x МАССИВ, то вызываем функцию еще раз...
А если нет? Если он ступенчатый массив, как было при первом вызове?
Мы его просто выводим на экран
C#
1
Console.Write("{0,5}", x);
Вообще запутался.
0
550 / 318 / 138
Регистрация: 08.02.2013
Сообщений: 609
13.10.2014, 11:29 14
CSharp_user, можно так:
C#
1
if (x Is Array)
вернет false если x не приводится к типу Array. Все массивы наследуются от класса Array в том числе и массивы массивов (ступенчатые). Из внешнего кода мы вызываем функцию для массива массивов, на первом уровне рекурсии - для массива int'ов, на втором - (x Is Array) == false и мы просто будем выводить int'ы на экран

Добавлено через 1 минуту
пройдитесь отладчиком и посмотрите что в x лежит
0
5 / 5 / 4
Регистрация: 11.10.2014
Сообщений: 57
16.10.2014, 14:19  [ТС] 15
Ну да, только сейчас заметил, что в метод Print передается не int[][], а Array... Тогда понятно, как он перебирает каждый элемент. Спасибо.
0
Эксперт .NET
16746 / 12497 / 3285
Регистрация: 17.09.2011
Сообщений: 20,730
16.10.2014, 15:07 16
Если не прятаться за линком и рекурсией, которые по сути своей являются вложенными циклами, то можно запилить итератор:

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
class JaggedArrayEnumerator<T> : IEnumerable<T>, IEnumerator<T>
{
    T[][] array;
    int outer, inner = -1;
 
    public JaggedArrayEnumerator(T[][] array)
    {
        this.array = array;
    }
 
    public T Current
    {
        get { return array[outer][inner]; }
    }
 
    object IEnumerator.Current
    {
        get
        {
            return array[outer][inner];
        }
    }
 
    public bool MoveNext()
    {
        inner++;
        if (inner == array[outer].Length)
        {
            inner = 0;
            outer++;
        }
        return outer < array.Length;
    }
 
    public void Reset()
    {
        outer = 0;
        inner = -1;
    }
 
    public IEnumerator<T> GetEnumerator()
    {
        return this;
    }
 
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
 
    public void Dispose()
    {
 
    }
 
}
C#
1
2
3
4
5
6
7
8
9
10
11
int[][] a = new int[10][];
 
for (int i = 0; i < a.Length; i++)
{
    a[i] = new int[i];
    for (int j = 0; j < a[i].Length; j++)
        a[i][j] = 100 * i + j;
}
 
foreach (var x in new JaggedArrayEnumerator<int>(a))
    Console.WriteLine(x);
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.10.2014, 15:07
Помогаю со студенческими работами здесь

Слияние двух циклов в один
Как из двух цыклов сделать 1 втаком коде? var a = 3, b = 5, c = 1, sum1 = 0, ...

Вывод двух разных массивов API в один foreach
Доброго времени суток, коллеги. Подскажите, как сделать такой же вывод как здесь...

Нужно переделать из двух циклов for в один цикл for
Народ у меня код считает сумму введенных элементов массив до последнего положительного элемента....

Ступенчатые массивы C#
Поменять местами строки массивов А1 и А2 по правилу: строка массива А1 с номером 0 меняется с...

Ступенчатые массивы
Приветы, как получить массив такого типа: &quot;Product&quot;, &quot;1&quot;, &quot;2&quot;, &quot;3&quot;]] , &quot;Product&quot;,...

Ступенчатые массивы
Ребята, нужно из строк (кроме последней) ступенчатой матрицы вычесть последнюю строку. Почему-то не...


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

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

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