Собеседование: самая любимая задача по ООП (C#)

Опубликовано Dec 26, 2012 в ООП, Простые проекты для учебы | 19 коммент.

, , ,

Собеседование: самая любимая задача по ООП (C#)
Эту задачу делают как лабораторную работу все и везде  и ее очень часто дают на собеседованиях как практический тест на владение основами ООП вместе с остальными абсолютно необходимыми вещами. Конкретно в этой постановке ее принесли откуда-то студенты. Скорее всего, она использовалась как реальная задача на каких-то собеседованиях, но восстановить первоисточник затруднительно, да и нет в этом особого смысла – по приведенному шаблону можно написать сотни условий.
 

ИТАК, САМА ЗАДАЧА

Построить три класса (базовый и 2 потомка), описывающих некоторых работников с почасовой оплатой (один из потомков) и фиксированной оплатой (второй потомок). Описать в базовом классе абстрактный метод для расчета среднемесячной заработной платы. Для «повременщиков» формула для расчета такова: «среднемесячная заработная плата = 20.8 * 8 * почасовую ставку», для работников с фиксированной оплатой «среднемесячная заработная плата = фиксированной месячной оплате».

  • a) Упорядочить всю последовательность работников по убыванию среднемесячного заработка. При совпадении зарплаты – упорядочивать данные по алфавиту по имени. Вывести идентификатор работника, имя и среднемесячный заработок для всех элементов списка.
  • b) Вывести первые 5 имен работников из полученного в пункте а) списка.
  • c) Вывести последние 3 идентификатора работников из полученного в пункте а) списка.
  • d) Организовать запись и чтение коллекции в/из файл.
  • e) Организовать обработку некорректного формата входного файла.

СРЕДСТВА И УСЛОВИЯ ВЫПОЛНЕНИЯ

Компьютер со знакомой соискателю IDE (подразумеваем MS Visual Studio) без доступа в Интернет и достаточно жесткие временные рамки такие, что времени на чтение документации, даже если к ней есть доступ, не хватит.

РЕКОМЕНДАЦИИ: КАК ДЕЛАТЬ НА СОБЕСЕДОВАНИИ

1) Как проектировать классы сущностей, – можно особенно не задумываться, все описано очень подробно, нужно только это реализовать. Разумеется, вводя поле/поля для хранения либо почасовой ставки, либо фиксированной месячной оплаты, нужно избежать дополнительных флагов, которые объясняют, что данное число обозначает (так сделает больше половины). Следовательно, опускаем эти данные в производные классы.
2) Необходим класс, реализующий полиморфный контейнер, над которым будут выполняться действия из пунктов a) – e). Вот здесь стоит сначала немного подумать – как наиболее оптимально еализовать сортировку, простейшие выборки и ввод/вывод с обработкой ошибок.

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

3) Еще нужно принять решение – делать контейнер статическим (например, Array) или динамическим (например, List<>). В условии нигде не упомянуты действия по удалению/добавлению объектов в контейнер. Следовательно, для реализации только описанной функциональности достаточно статического контейнера, размер которого определяется количеством актуальных данных во входном файле (любое количество объектов). Желательно избежать в коде присутствия цифирки, которая задает максимально возможное количество элементов контейнера. Программируя методы контейнерного класса, желательно продемонстрировать владение наиболее широким арсеналом средств языка.
4) Ввод/вывод. При всей банальности этого места, оно может оказаться проблемным. Во-первых, слишком много вариантов, и обычно тратится время на выбор какого-то из них. Во-вторых, нужен файл с исходными данными, то есть нужно определиться с его форматом и набить его без ошибок – а это может оказаться самой затратной по времени частью задачи.

Основная рекомендация здесь такая: все должно быть продумано заранее. То есть должен быть заготовлен хороший и апробированный способ  ввода табличных данных из текстового файла. Можно пользоваться своим собственным форматом, но лучше, разумеется, использовать стандартный XML, хотя для начинающих это обычно нетривиальная задача. XML с непривычки трудно набивать так, чтобы не запутаться, а если не будет работающего ввода, то и все остальное не сработает, даже если оно написано идеально.

Поэтому есть такой вариант. Входные данные первоначально генерируются программно с использованием каких-то рандомизаторов. Потом пишется функциональность вывода этих данных в файл – она ведь все равно требуется по условию. И в финале – пишем функциональность чтения данных из файла. Средства работы с XML в C# очень продвинутые – можно двумя-тремя строчками написать код, который прочитает/запишет любую таблицу в XML-файл стандартного формата. То есть о формате файла можно вообще не задумываться.

И еще – не забывайте, что классы потоков для работы с файлами наследуют IDisposable.

5) Обработка некорректного формата входного файла. Требование очень расплывчато для каких-то конкретных действий по поводу того, как должны выполняться задачи a), b), c) при каких-то (каких???) ошибках во входном файле.  Но всегда имеется входной файл, который может быть прочитан ожидаемым образом. Всякие другие форматы, скорее всего, при чтении сгенерируют  исключение. Его-то и нужно обработать простейшим образом – сообщить о нем пользователю и выйти из программы без выполнения каких-либо дальнейших действий.

Немалый опыт проверки подобных задач позволяет говорить о том, что достаточно часто студенты пишут такой метод ввода, который вроде бы срабатывает без индикации ошибок, но данные вводятся не так, как ожидалось, что, очевидно, является серьезным недочетом. И именно для этого пункта ввод/вывод через XML-сериализацию очень удобен. Если сравнивать его с самостоятельно написанным чтением из файла, то основное преимущество (кроме скорости разработки) состоит  в том, что в стандартный XML-формат уже заложено достаточно много проверок его корректности и любое их нарушение сгенерирует исключение.

Этот код рекомендуется к использованию для различных обучающих программ. Его ни в коем случае нельзя рассматривать как результат коммерческой деятельности компании FulcrumWeb


Автор публикации:

19 Коммент. : “Собеседование: самая любимая задача по ООП (C#)”

  1. Очень красивая реализация.

  2. lerev says:

    Только вот отсутствие комментариев не радует.

  3. Виталий says:
     
    using System;
    using System.IO;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace ConsoleApplication1
    {
        class Program
        {
     
     
            static void Main(string[] args)
            {
                int inn = 0;
                ArrayList DBEmp = new ArrayList();
     
                int menu = 0;
                while (menu != 6) 
                {
                    Console.Clear();
                    Console.WriteLine("Система расчета ЗП");
                    Console.WriteLine("1. Добавить сотрудника");
                    Console.WriteLine("2. Упорядочить всю последовательность работников по убыванию среднемесячного заработка.");              
                    Console.WriteLine("3. Вывести идентификатор работника, имя и среднемесячный заработок для всех элементов списка.");
                    Console.WriteLine("4. Запись коллекции в/из файл.");
                    Console.WriteLine("5. Чтение коллекции в/из файл.");
                    Console.WriteLine("6. Выход");
                    Console.WriteLine(Environment.NewLine);
                    Console.Write(">>>  ");
                    try
                    {
                        menu = int.Parse(Console.ReadLine());
                    }
                    catch 
                    {
                        Console.WriteLine("Не коректный ввод");
     
                    }
     
                    if (menu == 1)
                    {
                        int mn1 = 0;
                        while (mn1 != 3)
                        {
                            string lastName;
                            string firstName;
                            int hourlyRate=0;
                            int salary=0;
     
                            Console.Clear();
                            Console.WriteLine("Пункт добовления сотрудника в БД");
                            Console.WriteLine("1. Добавить сотрудника c почасовой оплатой ");
                            Console.WriteLine("2. Добавить сотрудника c фиксированной оплатой");
                            Console.WriteLine("3. Выход");
                            Console.WriteLine(Environment.NewLine);
                            Console.Write(">>>  ");
                            try
                            {
                                mn1 = int.Parse(Console.ReadLine());
                            }
                            catch
                            {
                                Console.WriteLine("Не коректный ввод");
     
                            }
     
     
                            if (mn1 == 1 || mn1 == 2) 
                            {
                                Console.WriteLine("Введите фамилию сотрудника:");
                                lastName = Console.ReadLine();
                                Console.WriteLine("Введите имя сотрудника");
                                firstName = Console.ReadLine();
                                if (mn1==1)
                                {
                                    Console.WriteLine("Введите почасовую ставку");
                                    try
                                    {
                                        hourlyRate = int.Parse(Console.ReadLine());
                                    }
                                    catch
                                    {
                                        Console.WriteLine("Не коректный ввод");
     
                                    }
                                    TimeEmployee Emp = new TimeEmployee();
                                    Emp.AddEmployee(inn,lastName,firstName);
                                    Emp.CalculationSalary(hourlyRate);
                                    inn++;
                                    DBEmp.Add(Emp);
                                }
                                if (mn1 == 2)
                                {
                                    Console.WriteLine("Введите зп сотрудника");
                                    try
                                    {
                                        salary = int.Parse(Console.ReadLine());
                                    }
                                    catch
                                    {
                                        Console.WriteLine("Не коректный ввод");
     
                                    }
                                    PermanentEmployee Emp = new PermanentEmployee();
                                    Emp.AddEmployee(inn, lastName, firstName);
                                    Emp.CalculationSalary(salary);
                                    inn++;
                                    DBEmp.Add(Emp);
     
                                }
                            }
     
     
                        }
                    }
     
                    if (menu==2)
                    {
                         int mn1 = 0;
                         while (mn1 != 4)
                         {
                             Employee[] SortEmpl = new Employee[DBEmp.Count];
                             for (int i = 0; i < DBEmp.Count; i++)
                             {
                                 SortEmpl[i] = (Employee)DBEmp[i];
                             }
                             double temp;
                             for (int i = 0; i < DBEmp.Count - 1; i++)
                             {
                                 for (int j = 0; j < SortEmpl.Length - i - 1; j++)
                                 {
                                     if (SortEmpl[j].middleSalary > SortEmpl[j + 1].middleSalary)
                                     {
                                         temp = SortEmpl[j].middleSalary;
                                         SortEmpl[j].middleSalary = SortEmpl[j + 1].middleSalary;
                                         SortEmpl[j + 1].middleSalary = temp;
                                     }
     
                                 }
     
                             }
     
                             Console.Clear();
                             Console.WriteLine("Пункт сортировки данных");
                             Console.WriteLine("Данные отсортированны согласно ТЗ:");
                             Console.WriteLine("Упорядочить всю последовательность работников по убыванию среднемесячного заработка.");
                             Console.WriteLine(Environment.NewLine);
                             Console.WriteLine("1.Вывести результат сортировки");
                             Console.WriteLine("2. Вывести первые 5 имен работников из полученного списка");
                             Console.WriteLine("3. Вывести последние 3 идентификатора работников из полученного списка");
                             Console.WriteLine("4. Выход");
                             Console.WriteLine(Environment.NewLine);
                             Console.Write(">>>  ");
                             try
                             {
                                 mn1 = int.Parse(Console.ReadLine());
                             }
                             catch
                             {
                                 Console.WriteLine("Не коректный ввод");
     
                             }
     
     
                             Console.WriteLine("");
                             Console.WriteLine("");
                             Console.WriteLine("");
     
                             if (mn1==1)
                             {
                                 for (int i = 0; i < SortEmpl.Length; i++)
                                 {
                                     Console.WriteLine("-------------" + i + "-------------");
                                     Console.WriteLine("Средняя ЗП : " + SortEmpl[i].middleSalary);
                                     Console.WriteLine("Номер : " + SortEmpl[i].inn);
                                     Console.WriteLine("Фамилия :  " + SortEmpl[i].lastName);
                                     Console.WriteLine("Имя : " + SortEmpl[i].firstName);
                                     Console.WriteLine("---------------------------");
                                     Console.WriteLine(Environment.NewLine);
                                 }
                                 Console.ReadKey();
     
                             }
                             if (mn1 == 2) 
                             {
                                 for (int i = 0; i < 5; i++)
                                 {
                                     Console.WriteLine("Фамилия :  " + SortEmpl[i].lastName);
                                 }
                                 Console.ReadKey();
                             }
                             if (mn1==3)
                             {
                                 for (int i = SortEmpl.Length-1; i > SortEmpl.Length-4; i--)
                                 {
                                     Console.WriteLine("Номер : " + SortEmpl[i].inn);
     
                                 }
                                 Console.ReadKey();
                             }
     
     
                         }
                    }
     
                    if (menu==3)
                    {
                        for (int i = 0; i < DBEmp.Count; i++)
                        {
                           Employee Emp = new Employee();
                           Emp = (Employee)DBEmp[i];
                           Console.WriteLine("---------------------------");
                           Console.WriteLine("Номер : " + Emp.inn);
                           Console.WriteLine("Фамилия :  " + Emp.lastName);
                           Console.WriteLine("Имя : " + Emp.firstName);
                           Console.WriteLine("Средняя ЗП : " + Emp.middleSalary);
                           Console.WriteLine("---------------------------");
                           Console.WriteLine(Environment.NewLine);
                        }
                        Console.ReadKey();
                    }
                    if (menu == 4) 
                    {
                        StreamWriter sw = new StreamWriter(@"D:\DB.txt");
     
                        Employee[] SortEmpl = new Employee[DBEmp.Count];
                        for (int i = 0; i < DBEmp.Count; i++)
                        {
                            SortEmpl[i] = (Employee)DBEmp[i];
                        }
                        for (int i = 0; i < SortEmpl.Length; i++)
    		        	{
    			            sw.WriteLine(SortEmpl[i].inn+","+SortEmpl[i].lastName+","+SortEmpl[i].firstName+","+SortEmpl[i].middleSalary);
    			        }
     
                        sw.Close();
                        Console.WriteLine("Произведина запись данных в БД");
                        Console.ReadKey();
                    }
                    if (menu==5)
                    {
     
     
     
     
                        int counter = 0;
                        string line;
                        string[] str= new string[100];
                        List<string> tempString = new List<string>();
                        StreamReader sw = new StreamReader(@"D:\DB.txt");
                        while ((line = sw.ReadLine()) != null)
                        {
                            Console.WriteLine(line);
                            tempString.Add(line);
     
                            counter++;
                        }
                        sw.Close();
     
                        for (int i = 0; i < counter; i++)
                        {
                            Employee LDEmp = new Employee();
                            string text = tempString[i];
                            string[] words = text.Split(',');
                            LDEmp.inn = int.Parse(words[0]);
                            LDEmp.lastName = words[1];
                            LDEmp.firstName = words[2];
                            LDEmp.middleSalary = double.Parse(words[3]);
                            DBEmp.Add(LDEmp);
     
                        }
     
     
                        Console.WriteLine("Загружено {0} значений: ", counter);
                        Console.ReadKey();
     
     
     
                    }
     
                }
            }
     
        }
     
     class Employee 
        {
            public int inn;
            public double middleSalary;
            public string lastName;
            public string firstName;
     
     
           public void AddEmployee(int inn, string lastName, string firstName) 
            {
                this.inn = inn;
                this.lastName = lastName;
                this.firstName = firstName;
     
            }
     
        }
       class TimeEmployee : Employee 
       {
     
           public void CalculationSalary(int hourlyRate) 
           {
     
               this.middleSalary = 20.8 * 8 * hourlyRate;
     
           }
       }
     
       class PermanentEmployee : Employee 
       {
           public void CalculationSalary(int salary) 
           {
     
               this.middleSalary = salary;
     
           }
     
       }
     
     
     
    }
    • Галина says:

      Решение скорее всего работающее, но запустить его проверяющему нереально, так как никто не будет вводить столько данных с клавиатуры.

      По коду, к сожалению, очень много классических мест НЕПРАВИЛЬНОГО использования принципов ООП.

      Много замечаний по способу использования массивов и коллекций – это не стиль современного C#, так учили программировать на паскале лет 20 назад.

      Через некоторое время я оформлю отдельным постом разбор ошибок, если не появится возражений автора по этому поводу.

      • Здравствуйте!
        Помню, при приеме на работу мне тоже задали именно эту задачу. Код был примерно как у Виталия, опыт изучения C# был менее недели. В итоге, сеньор, проводивший собеседование, сказал, что “у меня нет алгоритмического мышления” и “иди программируй микроконтролеры”.

  4. Виталий says:

    Конечно не против. Я учу C# всего 3 недели, по 2-3 часа в день. Поэтому любые замечания будут только положительно встречены. Если напишите, что можно почитать, буду очень благодарен.
    Сейчас начал Троелсена.

  5. The .Net programmer says:

    Файл XML должен выглядить таким образом,где атрибут type определяет является ли работник повременщик(type=0) или с фиксированной оплатой (type=1).
    Если работник повременщик,то в поле пишется количество часов. а для работника с фиксированной оплатой пишется фиксированная месячная оплата
    < ?xml version="1.0" encoding="utf-8" ?>


    1
    The .Net programmer
    8


    2
    programmer
    8000

    ………. etc.

    abstract class Employee
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public double Salary { get; set; }
            protected Employee(){}
            protected Employee(int id,string n,double salary)
            {
                Id = id;
                Name = n;
                Salary = salary;
            }
            public abstract double GetSalary(double salary);
        }
     class FixedSalaryEmployee:Employee
        {
            public FixedSalaryEmployee(int id,string name,double salary):base(id,name,salary)
            {
            }
            public override double GetSalary(double salary)
            {
                return salary;
            }
        }
     class HourlySalaryEmployee:Employee
        {
            public HourlySalaryEmployee(int id, string name, double salary)
                : base(id, name, salary)
            {
     
            }
     
            public override double GetSalary(double salary)
            {
                return 20.8*8*salary;
            }
        }
     class EmployeeContainer : List<Employee>
        {
            //Load XmlFile
            public void LoadXmlFile(string fileName)
            {
     
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.Load(fileName);
                XmlNodeList employeeType = xmlDocument.GetElementsByTagName("Employee");
                XmlNodeList employeeId = xmlDocument.GetElementsByTagName("id");
                XmlNodeList employeeNames = xmlDocument.GetElementsByTagName("name");
                XmlNodeList employeeSalary = xmlDocument.GetElementsByTagName("salary");
                for (int i = 0; i < employeeType.Count; i++)
                {
     
                    var xmlAttributeCollection = employeeType[i].Attributes;//get type of employee
                    if (xmlAttributeCollection != null && xmlAttributeCollection["type"].Value == "1")
                    {
     
                        this.Add(new FixedSalaryEmployee(int.Parse(employeeId[i].InnerText), employeeNames[i].InnerText,
                                                   double.Parse(employeeSalary[i].InnerText)));
                    }
                    else
                    {
                        this.Add(new HourlySalaryEmployee(int.Parse(employeeId[i].InnerText), employeeNames[i].InnerText,
                                                  double.Parse(employeeSalary[i].InnerText)));
                    }
                }
     
     
            }
            //Get the list of sorted employees
            public  List<Employee> SortEmployee()
            {
                var sortedEmployees = this.OrderByDescending(salary => salary.GetSalary(salary.Salary)).ThenBy(name=>name.Name).ToList();
                return sortedEmployees;
            }
            //Output the sorted employees
            public void SortedEmployees()
            {
                var getSortedEmployees = this.SortEmployee();
                foreach (var sortedEmployee in getSortedEmployees)
                {
                    Console.WriteLine(sortedEmployee.Name+"="+sortedEmployee.GetSalary(sortedEmployee.Salary));
                }
            }
            //Get the first five employees in (a) paragraph
            public void GetFirstFiveEmployees()
            {
                var getSortedEmployees = this.SortEmployee();
                Console.WriteLine("The first five employees");
                var five = getSortedEmployees.Take(5);
                foreach (var employee in five)
                {
                    Console.WriteLine(employee.Name);
                }
            }
            //Get the last three employees in (a) paragraph
            public  void GetTheLastThreeEmployees()
            {
                var getSortedEmployees = this.SortEmployee();
                Console.WriteLine("The last three employees");
                var three = getSortedEmployees.Skip(getSortedEmployees.Count-3).Take(3);
                foreach (var employee in three)
                {
                    Console.WriteLine(employee.Name);
                }
     
            }
        }
     
    class Program
        {
            static void Main(string[] args)
            {
                var fileName = "Employee.xml";
                if (File.Exists(fileName))
                {
                    EmployeeContainer container = new EmployeeContainer();
                    container.LoadXmlFile(fileName);
                    Console.WriteLine("\nparagraph a\n");
                    container.SortedEmployees();
                    Console.WriteLine("\nparagraph b\n");
                    container.GetFirstFiveEmployees();
                    Console.WriteLine("\nparagraph c\n");
                    container.GetTheLastThreeEmployees();
                }
                else
                {
                    Console.WriteLine("Not Found File");
                }
     
            }
        }
  6. The .Net programmer says:

    XML

    <Employees>
      <Employee type="0">
        <id>1</id>
        <name>The .Net programmer</name>
        <salary>8</salary>
      </Employee>
      <Employee type="1">
        <id>2</id>
        <name>Prog</name>
        <salary>8000</salary>
      </Employee>
    <!--lot of records-->
    <\Employees>
  7. Еще вариант

  8. kypiwindy says:
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Runtime.Serialization.Formatters.Binary;
     
    namespace ConsoleApplication1
    {
        [Serializable]
        abstract class Employee
        {
            public string Name { get; set; }
            public int Age { get; set; }
            public abstract decimal GetSalary { get; set; }
            protected Employee(string name, int age)
            {
                Name = name;
                Age = age;
            }
     
            protected abstract decimal Salary();
            public override string ToString()
            {
                return Name+" " + Age + " " + Salary();
            }
        }
        [Serializable]
        sealed class BadEmployee : Employee
        {
            public double Stavka { get; private set; }
     
            public BadEmployee(string name,int age,double stavka):base(name,age)
            {
                Stavka = stavka;
                GetSalary = Salary();
            }
     
            public override decimal GetSalary { get; set; }
     
            protected override decimal Salary()
            {
                return (decimal) (20.8*8*Stavka);
            }
        }
        [Serializable]
        sealed class GoodEmployee : Employee
        {
            public decimal Oklad { get;private set; }
            public GoodEmployee(string name,int age,decimal oklad):base(name,age)
            {
                Oklad = oklad;
                GetSalary = Salary();
            }
     
            public override decimal GetSalary { get; set; }
     
            protected override decimal Salary()
            {
                return Oklad;
            }
        }
     
     
        class Program
        { 
            static void Main(string[] args)
            {
                List<Employee> emp=new List<Employee>()
                {
                    new GoodEmployee("Dmitrenko",22,1000),
                    new GoodEmployee("Pipipenko",25,1500),
                    new GoodEmployee("Savchenko",14,800),
                    new BadEmployee("Filipchuk",20,15),
                    new BadEmployee("Konenko",20,10),
                    new BadEmployee("Uzun",25,11)
                };
                var punktA = emp.OrderBy(a => a.GetSalary);
     
                foreach (var e in punktA)
                {
                    Console.WriteLine(e);
                }
                Console.WriteLine(new string('*', 20));
     
                var punktB = punktA.Take(5);
                foreach (var e in punktB)
                {
                    Console.WriteLine(e);   
                }
     
                Console.WriteLine(new string('*', 20));
     
                foreach (var q in punktA.Take(3))
                {
                    Console.WriteLine(q.Name);
                }
     
                var binary=new BinaryFormatter();
     
                using (var fs=new FileStream("data.dat",FileMode.Create))
                {
                      binary.Serialize(fs,emp);
                Console.WriteLine("Даные записаны в data.dat");
                }
     
                try
                {
                  var res=  binary.Deserialize(File.Open("data.dat",FileMode.Open)) as List<Employee>;
                    foreach (var a  in res)
                    {
                        Console.WriteLine(a);
                    }
                }
                catch (Exception e)
                {
     
                    Console.WriteLine(e.Message);
                    Console.ReadKey();
                }
                Console.ReadKey();
            }  
        }
    }
    • Александр says:

      Прекрасное решение. Именно оно, кмк показывает хороший уровень владения стандартными средствами языка. Нужно не забывать, что это C# с его синтаксическим сахаром(LINQ, аттрибуты) и .Net с его всеобъемлющей FCL-библиотекой. А вот для C/C++ писать все самому было бы вполне понятным решением

  9. Anonymous says:

    Детям, беременным женщинам, студентам и слабонервным программистам не рекомендуется просматривать решения из комментариев!!!

    • :)
      Авторы этих решений написали так, как смогли. Понятно, что они ещё только учатся программировать. Попробуйте предложить конструктивные замечания к конкретным решениям – будет польза и для авторов, и для тех, кто их просматривает.

      • Александр says:

        Это комментарий как раз говорит о том, что решения хорошие, но непростные для неподготовленных. “Дети, студенты, беременные…”

  10. Alexander says:

    Не буду писать весь код, только ответы на 5 задач:
    a) Упорядочить по зарплате, если одинаково – по имени.
    Можно просто упорядочить по зарплате, потом по имени. Однако, если список будет большой (в реальной программе), то стоит переписать, дабы все не сортировалось постоянно.

    var ordered = employees.OrderByDescending(a => a.salary).ThenBy(a => a.name);

    b) Последние 5 из списка a. Ну тут просто методом Take(int count)

    var ordered employees.OrderByDescending(a => a.salary).ThenBy(a => a.name).Take(5);

    c) Вывести идентификатор последних 3 работников из списка a.
    Сортируем, применяем метод Reverse() и берем 3 работников, которые после Reverse будут находится первыми.
    Можно было сделать Skip(count – 3) возможно при больших данных будет быстрее. Опять же мы говорим о конкретной задачи, ограничений нам не дано.

    var ordered = employees.OrderByDescending(a => a.salary).ThenBy(a => a.name).Reverse().Take(3);

    Ну остальное это работа с файлами, не буду засорять комменты.

  11. phen0men says:

    Employee.java

    import java.util.ArrayList;
    import java.util.Comparator;
     
    public abstract class Employee {
        private int base_id;
        private String base_name;
     
        public int getEmployeeID () {
            return this.base_id;
        }
     
        public int setEmployeeID (int value) {
            return this.base_id = value;
        }
     
        public String getEmployeeName () {
            return this.base_name;
        }
     
        public String setEmployeeName(String value) {
            return this.base_name = value;
        }
     
        public abstract double getMonthSalary();
     
        public static void showArrayList(ArrayList<Employee> ArrayList) {
            for (int i = 0; i < ArrayList.size(); i++) {
                System.out.println(ArrayList.get(i));
            }
        }
     
        public static void showArrayListSalary(ArrayList<Employee> ArrayList) {
            for (int i = 0; i < ArrayList.size(); i++) {
                System.out.println(ArrayList.get(i).getMonthSalary());
            }
        }
     
        public static void taskA(ArrayList<Employee> ArrayList) {
            System.out.println("Original ArrayList: ");
            showArrayList(ArrayList);
            System.out.println("\nOriginal salary list: ");
            showArrayListSalary(ArrayList);
     
            ArrayList.sort(Comparator.comparing(Employee::getMonthSalary).reversed().
                    thenComparing(Employee::getEmployeeName));
     
            System.out.println("\nSorted ArrayList: ");
            showArrayList(ArrayList);
            System.out.println("\nSorted salary list: ");
            showArrayListSalary(ArrayList);
        }
     
        public static void taskB(ArrayList<Employee> ArrayList) {
            System.out.println("\n");
            for (int i = 0; i < ArrayList.size(); i++) {
                System.out.println(ArrayList.get(i).getEmployeeName());
            }
        }
     
        public static void taskC(ArrayList<Employee> ArrayList) {
            System.out.println("\n");
            for (int i = 3; i > 0; i--){
                System.out.println(ArrayList.get(ArrayList.size() - i).getEmployeeID());
            }
     
        }
     
        public static void main(String[] argc) {
            ArrayList<Employee> employees = new ArrayList<Employee>();
            employees.add(new PerHourEmployee(1, "asd", 1300));
            employees.add(new FixedEmployee(7, "asds", 14025));
            employees.add(new PerHourEmployee(2, "nikan", 1230));
            employees.add(new PerHourEmployee(3, "nikalo", 12330));
            employees.add(new FixedEmployee(8, "aaaa", 14025));
            employees.add(new FixedEmployee(4, "nikaq", 140210));
            employees.add(new FixedEmployee(5, "nikas", 124000));
            employees.add(new FixedEmployee(6, "nikab", 14025));
     
            System.out.print("Task A: ");
            taskA(employees);
            System.out.print("\nTask B: ");
            taskB(employees);
            System.out.print("\nTask C: ");
            taskC(employees);
            // etc
        }
    }

    PerHourEmployee.java

    public class PerHourEmployee extends Employee {
        private double salary;
     
        public PerHourEmployee() {}
     
        public double getSalaryPerHour() { return this.salary; }
     
        public double setSalaryPerHour(double value) {
            return this.salary = value;
        }
     
     
        public PerHourEmployee(int _id, String _name, double _salary) {
            setEmployeeID(_id);
            setEmployeeName(_name);
            this.salary = _salary;
        }
     
        public double getMonthSalary() {
            return salary * (20 * 0.8);
        }
     
        public String toString() {
            return getEmployeeID() + ", " + getEmployeeName() + ", " + getSalaryPerHour();
        }
    }

    FixedEmployee.java

    public class FixedEmployee extends Employee {
        private double salary;
     
        public FixedEmployee() {}
     
        public double getSalaryFixed() {
            return this.salary;
        }
     
        public double setSalaryFixed(double value) {
            return this.salary = value;
        }
     
        public FixedEmployee(int _id, String _name, double _salary) {
            setEmployeeID(_id);
            setEmployeeName(_name);
            this.salary = _salary;
        }
     
        public double getMonthSalary() {
            return this.salary;
        }
     
        public String toString() {
            return getEmployeeID() + ", " + getEmployeeName() + ", " + getSalaryFixed();
        }
     
    }
  12. using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Collections;
    using System.Xml.Serialization;
    using System.IO;
    namespace ConsoleApplication3
    {   
        class Program
        {
     
            static void Main(string[] args)
            {
                XmlSerializer serializer = new XmlSerializer(typeof(List<Employee>));
                List<Employee> emp = new List<Employee>();
                using (FileStream stream = new FileStream("employees.xml", FileMode.OpenOrCreate))
                {
                    try
                    {
                        emp = (List<Employee>)serializer.Deserialize(stream);
                    }
                    catch(InvalidOperationException e)
                    {
                        Console.WriteLine("Wrong format");
                    }
     
                }
     
                //1.Task
                Console.WriteLine("Task 1");
                List<Employee> sorted = emp.OrderByDescending(x => x.getSalary(20.8)).ThenBy(x=>x.Name).ToList();
                showData(sorted);
                Console.WriteLine("Task 2");
                Console.WriteLine();
                //2.Task           
                sorted = emp.OrderBy(x => x.Name).Take(5).ToList();
                showData(sorted);
                //3.Task
                Console.WriteLine("Task 3");
                Console.WriteLine();
                sorted = emp.OrderByDescending(x => x.id).Take(3).ToList();
                showData(sorted);
                //4.Task       
                using (FileStream stream=new FileStream("employees.xml",FileMode.OpenOrCreate))
                {
                    serializer.Serialize(stream, emp);
                }
                Console.WriteLine("Method ended");
                    Console.Read();
            }
            static void showData(List<Employee> sorted)
            {
                foreach (Employee employee in sorted)
                {
                    Console.WriteLine($" {employee.id} {employee.Name} {employee.SecondName} {employee.Age} {employee.getSalary(20.8)}");
                }
            }
     
        }
        [XmlInclude(typeof(TempEmployee))]
        [XmlInclude(typeof(ConstantEmployee))]
        [Serializable]
        public abstract class Employee
        {
            public Guid id { get; set; }
            public string Name { get; set; }
            public string SecondName { get; set; }
            public int Age { get; set; }
            public abstract double getSalary(double daysToWork);
        }
        [Serializable]
        public class TempEmployee :Employee
        {
            public double Payment { get; set; }
            public override double getSalary(double daysToWork)
            {
                return daysToWork*8* this.Payment;
            }
        }
        [Serializable]
        public class ConstantEmployee :Employee
        {
            public double Payment { get; set; }
            public override double getSalary(double daysToWork)
            {
                return ((daysToWork/DateTime.DaysInMonth(DateTime.Now.Year,DateTime.Now.Month))* this.Payment);
            }
        }
     
    }

Оставить комментарий

Ваш адрес email не будет опубликован.


*