Работа с массивами

Рейтинг: 0Ответов: 2Опубликовано: 12.02.2015

Здравствуйте.

Задача такая: пользователь вводит с клавиатуры две строки с числами, например:

10 0 31 301 15
01 301 31 105
да

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
    using System.Threading.Tasks;

namespace L1_T1
{
    class Program
    {
        static void Main(string[] args)
        {
            ///////////////////////////////////////////////// 
            //первая строка
            ////////////////////////////////////////////////
            string[] s1;    // массив строк для разбивки строки на числа
            string s = "";
            int[] Data = new int[100]; // максимальное возможное количество
            int N = 0;    // количество чисел в массиве
            Console.WriteLine("Введите первую строку:");
            s = Console.ReadLine();
            // разбивать строку по пробелам и табуляциям убрав пустые элементы
            s1 = s.Split(new char[] { ' ', '\t' },
                StringSplitOptions.RemoveEmptyEntries);
            int i;
            for (i = 0; i < s1.Length; i++)        // s1[0]=2 s1[1]=4 s1[2]=6
            {
                Data[N] = Convert.ToInt32(s1[i]);
                N++;
            }
            for (i = 0; i < N; i++)
            {
                Console.WriteLine(Convert.ToString(Data[i]));
            }
            //////////////////////////////////////////
            //вторая строка
            //////////////////////////////////////////

            string r = "";
            int[] Data1 = new int[100]; // максимальное возможное количество
            int M = 0;    // количество чисел в массиве
            Console.WriteLine("Введите вторую строку:");
            r = Console.ReadLine();
            // разбивать строку по пробелам и табуляциям убрав пустые элементы
            s1 = r.Split(new char[] { ' ', '\t' },
                StringSplitOptions.RemoveEmptyEntries);
            for (i = 0; i < s1.Length; i++)        // s1[0]=2 s1[1]=4 s1[2]=6
            {
                Data1[M] = Convert.ToInt32(s1[i]);
                M++;
            }
            for (i = 0; i < M; i++)
            {
                Console.WriteLine(Convert.ToString(Data1[i]));
            }
            //////////////////////////////////////////////////////

            Console.ReadKey();

        }
    }
}

Ответы

▲ 1Принят

Как-то так. Главная идея заключается в том, чтобы иметь два обходчика. Каждый обходчик игнорирует все символы, кроме цифр. Как только один обходчик встретил цифру, он останавливает свой ход. Когда второй обходчик встречает цифру, две цифры сравниваются. Если они равны, мы их сбрасываем и продолжаем обход, иначе строки не равны, выходим. После того, как обошли обе строки, проверяет, не осталось ли лишних цифр (s1 = "01", s2 = "11"). Если остались, выходим.

Код написан на скорую руку, протестирован на исходном примере и паре примеров попроще. Так что могут быть ошибки, да и наверное попроще можно написать :).

    static void Main(string[] args)
    {
        string s1 = Console.ReadLine();
        string s2 = Console.ReadLine();

        bool result = true;

        char? lastDigit1 = null;
        char? lastDigit2 = null;

        int index1 = 0;
        int index2 = 0;

        while ((index1 < s1.Length) || (index2 < s2.Length))
        {
            // идем, пока строка не кончилась и пока не встретили очередную цифру
            if (index1 < s1.Length && !lastDigit1.HasValue)
            {
                if (char.IsDigit(s1[index1]))
                {
                    if (s1[index1] != '0')
                    {
                        // если цифра и не ноль, запоминаем,
                        // в остальных случаях двигаемся дальше
                        lastDigit1 = s1[index1];
                    }
                }
                index1++;
            }

            // идем, пока строка не кончилась и пока не встретили очередную цифру
            if (index2 < s2.Length && !lastDigit2.HasValue)
            {
                if (char.IsDigit(s2[index2]))
                {
                    if (s2[index2] != '0')
                    {
                        // если цифра и не ноль, запоминаем,
                        // в остальных случаях двигаемся дальше
                        lastDigit2 = s2[index2];
                    }
                }
                index2++;
            }

            // если есть две цифры для сравнения
            if (lastDigit1.HasValue && lastDigit2.HasValue)
            {
                if (lastDigit1 == lastDigit2)
                {
                    // цифры равны, продолжаем обход
                    lastDigit1 = null;
                    lastDigit2 = null;
                }
                else
                {
                    // строки не равны, выходим
                    result = false;
                    break;
                }
            }
        }

        // если в результате обхода осталась "лишняя" цифра, то строки тоже не равны
        if (lastDigit1.HasValue != lastDigit2.HasValue)
        {
            result = false;
        }

        Console.WriteLine(result);
        Console.ReadLine();
    }
▲ 1

Эх. Учебные задания такие учебные задания.

Такие вещи пишутся в одну строчку на любой функциональщине. Например, LINQ:

var c1 = Console.ReadLine().Split().Select(Convert.ToInt32);
var c2 = Console.ReadLine().Split().Select(Convert.ToInt32);

var equalsIgnoringZeroes = Enumerable.SequenceEqual(
             c1.Where(n => n != 0), c2.Where(n => n != 0));
Console.WriteLine(equalsIgnoringZeroes ? "да" : "нет");

(Nitpicker's corner: поскольку у LINQ ленивые вычисления, промежуточные коллекции не материализуются.)