Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
Axe1St
0 / 0 / 1
Регистрация: 29.10.2016
Сообщений: 19
1

Работа с отрезками

02.12.2016, 13:09. Просмотров 498. Ответов 1
Метки нет (Все метки)

Работа с отрезками. Что-то делаю не правильно, нужна помощь.
По условию:

Файл in.txt cодержит корректные вещественные координаты отрезков на плоскости (по одному отрезку в строке) в формате:
(x1;y1) (x2;y2)
1 Создать список вида (len; num) где len – длина отрезка, округлённая до целого значения, а num – количество отрезков длины len.
2) Отсортировать список по убыванию num.

Пример файла in.txt:
(0 ; 0) ( 2,5; 0)
( 0;1) ( 0; 2 )
(-3,0; 20,1e-1) (-2;2)
Вывод:
1;2
3;1


Замечания к задаче 2
– Информационный класс, как обычно, описать в отдельном файле. Считывание файла данных и необходимые действия реализовать в методе Main() приложения.
– Строку разобрать методом split( ) через регулярное выражение. Формат строки (неформально):
\s*(\s*вещ.число\s*;\s*вещ.число\s*)\s*(\s*вещ.число\s*;\s*вещ.число\s*)\s*
Вещественное число во входной строке правильное. Пары скобок и точка с запятой между числами гарантированно имеются. Учитывать данные усло-вия при составлении регулярного выражения. Не нужно подбирать выраже-ние под вещественное число. Оно далеко не тривиальное.
– Для поиска элемента в коллекции использовать метод BinarySearch( ) коллекции. Цикл с линейным поиском элемента запрещается, т.к. очень не-эффективный.
– Для корректной работы BinarySearch() нужно, чтобы список всегда был отсортирован. Возвращаемое значение в случае неудачного поиска может быть использовано для получения индекса, куда нужно вставить новый эле-мент с сохранением упорядоченности массива. Об этом подробнее есть в ссылке в задании.
– BynarySearch() использует IComparable< >, а Sort() – IComparer<Segment>. Это позволяет в одном классе иметь два метода сравнения: один по длине отрезка (нужен для поиска BynarySearch()), а второй – по количеству (для сортировки перед выводом).
– Длина отрезка = sqrt((x1– x2)2 + (y1–y2)2) – это на всякий случай ;
– чтобы половинные значения округлялись к большему, нужно вызы-вать Math.Round(…,MidpointRounding.AwayFromZero).

Наработки
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
    class Coordinates
    {
        double x1, x2;
        double y1, y2;
        string[] coordinates;
 
        public Coordinates() { }
        public Coordinates(string line)
        {
            coordinates = Regex.Replace(line, " ", "").Split('(', ')', ';');
            string[] lines= { "", "", "", "" };
            int temp = 0;
            foreach (var evidence in coordinates)
            {
                if (evidence != "")
                {
                    lines[temp] = evidence;
                    temp++;
                }
            }
            x1 = Double.Parse(lines[0]);
            y1 = Double.Parse(lines[1]);
            x2 = Double.Parse(lines[2]);
            y2 = Double.Parse(lines[3]);
        }
 
 
        public double CalculateLength()
        {
            return (Math.Round((Math.Sqrt(Math.Pow((x1 - x2), 2) + Math.Pow((y1 - y2), 2))), MidpointRounding.AwayFromZero));
        }
 
    }
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
    class Segment : IComparer<Segment>, IComparable<Segment>
    {
        public double Len { get; set; }
        public int Num { get; set; }
 
        public Segment() { }
        public Segment(double len,int num = 0)
        {
            Len = len;
            Num = num;
        }
        
 
        public override string ToString()
        {
            return String.Format("{0},{1}", Len, Num);
        }
 
 
 
        public int Compare(Segment x, Segment y)
        {
            return (y.Len.CompareTo(x.Len));
        }
 
        public int CompareTo(Segment other)
        {
            return other.Num.CompareTo(Num);
            
        }
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
        static void Main(string[] args)
        {
            Coordinates s = new Coordinates();
            Sort sort = new Sort();
 
            string[] lines = File.ReadAllLines(@"..\..\in.txt");
            foreach (var l in lines)
            {
                s = new Coordinates(l);
                var temp = s.CalculateLength();
 
               var seger = new List<Segment>();
                
                AddSegmentList(seger, temp);
 
                foreach (var e in seger) Console.WriteLine(e);
               
 
            }
            Console.ReadKey();
 
        }
        static void AddSegmentList(List<Segment> List,double len)
        {
            Segment seg = new Segment(len: len, num: 1);
            int index = List.BinarySearch(seg, new Sort());
            if (index >= 0)
            {
                List[index].Num++;
            }
            else
            {
                List.Insert(~index, seg);
            }
        }
В чем я ошибся и как подправить до работающего правильного вывода?

Добавлено через 5 минут
В чем я ошибся и как подправить до работающего правильного вывода?
В выводе не считает кол-во, т.е. не суммирует счетчик + по записи может можно как-то проще
http://joxi.ru/Y2L4Ox7tX7np26
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.12.2016, 13:09
Ответы с готовыми решениями:

Найти максимальное покрытие отрезками
На прямой взят отрезок, скажем , также на вход подается k отрезков, разной...

Площади частей прямоугольника разрезаемого отрезками
Дан прямоугольник на координатной плоскости с левым нижним углом в точке (0,...

Можно ли загружать данные из XML документа не полностью,а "отрезками" ?
Например ,у меня есть коллекция объектов , группируемых по ключу ,можно ли...

Нужна летиратура, в которой бы описывались работа с событиями, работа с элементами управления
Помогите пожалуйста найти летиратуру, в которой бы описывались работа с...

Работа с INI: некорректная работа пользовательской функции
Ранее нашел код для работы с ini-файлами: public class INI { ...

1
Aael
411 / 305 / 178
Регистрация: 02.06.2016
Сообщений: 538
Завершенные тесты: 1
02.12.2016, 15:14 2
Цитата Сообщение от Axe1St Посмотреть сообщение
– BynarySearch() использует IComparable< >, а Sort() – IComparer<Segment>. Это позволяет в одном классе иметь два метода сравнения: один по длине отрезка (нужен для поиска BynarySearch()), а второй – по количеству (для сортировки перед выводом).
много в этом смысла... Получается, нужен класс Segment, который умеет сравнивать сам себя с другими отрезками как IComparable, а также сравнивать другие отрезки как IComparer. При этом, для заполнения списка нужно использовать интерфейс IComparable, а перед выводом отсортировать с помощью IComparer.
Цитата Сообщение от Axe1St Посмотреть сообщение
В чем я ошибся и как подправить до работающего правильного вывода?
Во-первых Вы перепутали IComparer с IComparable:
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
class Segment : IComparable<Segment>, IComparer<Segment>
{
    public double Len { get; set; }
    public int Num { get; set; }
 
    public Segment() { }
    public Segment(double len, int num = 0)
    {
        Len = len;
        Num = num;
    }
 
    public override string ToString()
    {
        return String.Format("длина: {0}, число отрезков: {1}", Len, Num);
    }
 
    // IComparable позволяет сравнивать по длине
    int IComparable<Segment>.CompareTo(Segment other)
    {
        return (Len.CompareTo(other.Len));
    }
 
    // IComparer для сравнения количества
    int IComparer<Segment>.Compare(Segment x, Segment y)
    {
        return x.Num.CompareTo(y.Num);
    }
}
А во-вторых вместо одного списка для всех отрезков создаете по списку для каждого:
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
class Program
{
    static void Main(string[] args)
    {
        string[] lines = File.ReadAllLines(null);
        List<Segment> segments = new List<Segment>(); // Общий список для всех отрезков
        foreach (var l in lines)
        {
            Coordinates s = new Coordinates(l);
            var len = s.CalculateLength();
            AddToSegmentsList(segments, len);
        }
        segments.Sort(new Segment()); // IComparer<Segment>.Compare
        foreach (var e in segments) Console.WriteLine(e);
 
        Console.ReadKey();
    }
 
    static void AddToSegmentsList(List<Segment> List, double len)
    {
        Segment seg = new Segment(len: len, num: 1);
        int index = List.BinarySearch(seg); // IComparable<Segment>.CompareTo
        if (index >= 0)
        {
            List[index].Num++;
        }
        else
        {
            List.Insert(~index, seg);
        }
    }
}
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.12.2016, 15:14

Работа с векторами и отрезками
помогите пожалуйста разобраться с реализацией неизменяемого класса Vector,...

Задача с отрезками
Даны координаты концов n отрезков на числовой прямой. Определить отрезок,...

Расстояние между отрезками
Нужно найти минимальное и масимальное расстояние между отрезками. Построив виде...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru