Member 12714658 Ответов: 3

Как мне решить эту проблему C#


У нас есть входной текстовый файл, содержащий предложения.

Каждое предложение ограничено“.”, “!”, “?”
Каждое предложение содержит слова, разделенные одним или несколькими “ ”.

Программа должна быть написана, чтобы прочитать текстовый файл, найти предложения, отсортировать их и записать обратно в выходной файл.

Выходной файл должен состоять из одного предложения на строку.

Критериями для сортировки являются:
1) предложение больше, чем другое, если оно содержит больше одинаковых слов
2) предложение больше, если содержит больше слов
3) предложение больше, если содержит больше символов

Критерии должны применяться в порядке 1, 2, 3

Пример входного файла:

Привет, Мир. Привет, привет, прекрасный мир! Есть
больше слов в мире, чем миров в слове. Это
предложение. Меня зовут Нео.

Ожидаемые результаты файла:

Привет, привет, прекрасный мир!
В мире больше слов, Чем миров в слове.
Это предложение.
Меня зовут Нео.
Привет, Мир.

Я написал методы проверки количества слов, количества букв и повторения слов. Я не понимаю, как перебирать предложения и сортировать их

class CountWords
{
    static void Main(string[] args)
    {

        string text = File.ReadAllText("../../words.txt");

        string[] sentences = Regex.Split(text, @"(?<=[\.!\?])\s");
        
        var wordsCount = new int[sentences.Length];

        for (int i = 0; i < sentences.Length; i++)
        {
            var biggest = sentences[0];

        }


       
    }
    public int[] WorldCounter(string[] sentences)
    {
        var wordsCount = new int[sentences.Length];

        for (int i = 0; i < sentences.Length; i++)
        {
            wordsCount[i] = sentences[i]
                                .Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries)
                                .Count();
        }

        return wordsCount;
    }

    public int[] LetterCounter(string[] sentences)
    {
        return sentences
                .Select(c => c.Length)
                .ToArray();
    }

    public int[] DublicatesCounter(string[] sentences)
    {
        int[] dublicates = new int[sentences.Length];

        for (int i = 0; i < sentences.Length; i++)
        {
            var splited = sentences[i].Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);

            bool[] isChecked = new bool[splited.Length];

            for (int j = 0; j < splited.Length - 1; j++)
            {
                var currentWord = splited[j];

                for (int k = j + 1; k < splited.Length; k++)
                {
                    if (isChecked[k])
                    {
                        continue;
                    }

                    if (currentWord == splited[k])
                    {
                        dublicates[i]++;
                        isChecked[k] = true;
                    }
                }
            }
        }

        return dublicates;
    }
}

Richard MacCutchan

У вас есть вопрос?

Member 12714658

Мой вопрос в том, как мне перебирать предложения и сортировать их. Я написал методы, которые проверяют критерии, но я застрял там.

Richard MacCutchan

Вы можете использовать Массив.Метод Сортировки (Система)[^] для сортировки простого массива строк.

Mehdi Gholam

Похоже на домашнюю работу.

Member 12714658

Я самоучка. У меня нет домашних заданий :)

Member 12714658

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

Richard MacCutchan

Если у вас есть массив элементов, вы можете использовать foreach построить такой:

foreach (string str in sentences)
{
// for each iteration str will refer to the next element in the list
}

BillWoodruff

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

http://www.introprogramming.info/english-intro-csharp-book/

В информации в нижней части этой веб-страницы содержатся некоторые замечательные ресурсы для программирования .NET.

твое здоровье, Билл

3 Ответов

Рейтинг:
26

DimitriStPi

Привет!

Во-первых, кажется, что ожидаемый результат-это не тот, который уважает ваши правила.

"В мире больше слов, Чем миров в слове" должно быть первым, так как оно содержит два дубликата : "в" и "то".

Ожидаемый результат уже сейчас :
В мире больше слов, Чем миров в слове.
Привет, привет, прекрасный мир!
Это предложение.
Меня зовут Нео.
Привет, Мир.

После этого вот мое предложение :

Как насчет создания класса с пользовательским Sort() метод.
Это не возможно, чтобы переопределить Sort() метод класса String, так как этот класс является запечатанным.

Поэтому мы создаем класс только для того, чтобы инкапсулировать ваш String и создайте свой собственный Sort() метод.
Давайте назовем этот класс CustomString.

Для того чтобы иметь возможность использовать Sort() метод, вы должны реализовать IComparable интерфейс. Чтобы реализовать этот интерфейс, все, что вам нужно сделать, это создать метод CompareTo().

CompareTo указывает, как следует сравнивать два элемента. Хороший момент заключается в том, что вы знаете свои элементы сравнения :
- Повторяющиеся слова
- Количество слов
- Количество символов

Вот смотри, как реализовать интерфейс :

Сортировка списков с использованием интерфейса IComparable и IComparer в .NET

А после, вы просто должны использовать Sort() в вашем списке CustomString.


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

80% кода-ваш.

Решение :

using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

namespace CustomCompare
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            //Your code
            var text = File.ReadAllText("Your File");

            var sentences = Regex.Split(text, @"(?<=[\.!\?])\s");

            //Will contain the sorted elements 
            var sortedList = sentences.Select(sentence => new CustomString(sentence)).ToList();

            //Simple Sort call 
            sortedList.Sort();

            //Display
            foreach (var customString in sortedList)
            {
                Console.WriteLine(customString.CustString);
            }
            //Wait to be able to read output
            Console.Read();
        }
    }

    internal class CustomString : IComparable<CustomString>
    {
        //Simple constructor
        public CustomString(string custString)
        {
            CustString = custString;
        }

        //The encapsulated string 
        public string CustString { get; set; }
        //The implementation of compare to. 
        public int CompareTo(CustomString other)
        {
            //We compare the number of duplicated words
            var thisNumberOfDuplicate = DublicatesCounter(CustString);
            var otherNumberOfDuplicate = DublicatesCounter(other.CustString);

            if (thisNumberOfDuplicate > otherNumberOfDuplicate)
                return -1;
            if (thisNumberOfDuplicate < otherNumberOfDuplicate)
                return 1;

            //We compare the number of words
            var thisNumberOfWords = WordCounter(CustString);
            var otherNumberOfWords = WordCounter(other.CustString);

            if (thisNumberOfWords > otherNumberOfWords)
                return -1;
            if (thisNumberOfWords > otherNumberOfWords)
                return 1;

            //We compare the number or characters
            var thisNumberOfCharacter = LetterCounter(CustString);
            var otherNumberOfCharacter = LetterCounter(other.CustString);

            if (thisNumberOfCharacter > otherNumberOfCharacter)
                return -1;
            if (thisNumberOfCharacter < otherNumberOfCharacter)
                return 1;
            return 0;
        }

        //Your code without array
        private int WordCounter(string sentence)
        {
            var wordsCount = 0;
            wordsCount = sentence
                .Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries)
                .Count();
            return wordsCount;
        }

        //Your code without array 
        private int LetterCounter(string sentence)
        {
            return sentence.Length;
        }

        //Your code without array 
        //Modified because Hello != hello
        //Your expected output expects that Hello = hello
        //So you need to add .toLower()
        private int DublicatesCounter(string sentence)
        {
            var numberOfDuplicate = 0;

            var splited = sentence.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries);
            var isChecked = new bool[splited.Length];

            for (var j = 0; j < splited.Length - 1; j++)
            {
                var currentWord = splited[j];

                for (var k = j + 1; k < splited.Length; k++)
                {
                    if (isChecked[k])
                    {
                        continue;
                    }

                    if (currentWord.ToLower() == splited[k].ToLower())
                    {
                        numberOfDuplicate++;
                        isChecked[k] = true;
                    }
                }
            }
            return numberOfDuplicate;
        }
    }
}


Выход:

There are more words in the world than worlds in the word.
Hello hello beautiful world!
This is a sentence.
My name is Neo.
Hello World.


Member 12714658

Большое вам спасибо! Я даже не видел вашего решения со своего телефона. В этом есть смысл. Хотя это действительно звучит страшно, когда вы описываете это. Я взглянул на него и немного поиграл с решением, которое вы дали. Я получу большую часть этого, изменю все вокруг, чтобы мне было комфортно с этим. И в этом есть смысл. Ты даже прошел лишнюю милю. Спасибо!

DimitriStPi

Привет,
Пожалуйста.
Если что-то еще неясно, я могу вам помочь.
Самое главное, чтобы вы поняли идею, лежащую в основе решения !

Рейтинг:
2

Richard MacCutchan

Для самообразования очень полезна следующая книга: .Остаточная ноль, Чарльз Петцольд[^].


Member 12714658

Большое вам спасибо, я все проверю. Очень ценю это. Я занимаюсь front-end, но хочу расширить свои знания. Но я действительно хочу докопаться до сути этой проблемы. Но я что-то не понимаю. Надеюсь, я не говорю глупо. :\

Richard MacCutchan

Вовсе нет, вы явно приложили усилия, чтобы решить свою проблему. И помните, как и вы, мы все когда-то были трудными учениками.

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

Member 12714658

Честно говоря, я борюсь со всей этой проблемой. Но я понимаю, что у меня есть текст, который я должен получить и разделить на...!? тогда я остаюсь с массивом, где элементы массива-это предложения. Каждый элемент-это предложение, верно? Затем я должен повторить эти предложения, проверить критерии и сравнить каждое предложение с каждым из других предложений. Я создал методы для того, чтобы правила застряли там. Я думаю, что понимаю логику, но мне трудно выполнить всю программу на C#. Было бы слишком много просить, если бы вы могли написать, как это делается от начала до конца. Я боролся с этим 2 дня. Я не хочу оставлять это нераскрытым.

Richard MacCutchan

Я не думаю, что смогу это сделать, так как у меня есть другие вызовы в мое время. Использование простого Array.Sort метод отсортирует Ваш массив в алфавитном порядке. Однако ваши критерии нестандартны, поэтому вам нужно будет написать свою собственную процедуру сравнения для выполнения сортировки и использовать эту альтернативу Массив.Метод Сортировки (Массив, IComparer) (System)[^Пример кода на этой странице показывает вам основную идею. Вы получите два объекта рефенса, которые будут вашими двумя предложениями. Вам нужно разбить их на массивы, чтобы вы могли проверить наличие одинаковых слов, количество слов и количество символов. Это звучит сложнее, чем должно быть, и вы можете сделать это поэтапно. Во-первых, просто реализуйте сравнение количества слов, которое довольно просто:

string[] sentenceOne = x.split(' ');
string[] sentenceTwo = y.split(' ');
// < 0 sentenceOne has fewer words
// = 0 both have the same number
// > 0 sentenceOne has more words
return sentenceOne.Length - sentenceTwo.Length;

Обратите внимание, что я еще не тестировал это, поэтому оно может нуждаться в модификации.

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

Member 12714658

Спасибо, что потратили на это время. Я ценю это. Вы были очень милы и услужливы.

Рейтинг:
1

OriginalGriff

Начните с рассмотрения проблемы: алгоритм сортировки состоит из трех фаз:
1) равные слова
Затем
2) количество слов
Окончательно
3) количество символов.
Последние два довольно тривиальны.
Первое тоже несложно.
Начните с того, что возьмите строковые массивы, содержащие слова, и отсортируйте их:

Array.Sort(words);
будут делать это.
Теперь одинаковые слова находятся рядом друг с другом, и их очень легко обнаружить в цикле:
int copies = 0;
string lastWord = null;
foreach (string word in words)
    {
    if (word == lastWord) copies++;
    lastWord = word;
    }


Member 12714658

Я много боролся с этим не могу заставить его работать

OriginalGriff

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

Member 12714658

Когда я сказал "самообразование", я не имел в виду, что никогда не читал книг и не делал никаких упражнений. Я решил много проблем с массивами и условными операторами, циклами. Я специализируюсь в другой части мира программирования. Мне трудно работать со строками в c#, а как мы знаем, строки в js еще более запутаны. Я хотел посмотреть, как решается эта проблема. Это всегда так, когда вы видите, что это решение имеет смысл для вас.

OriginalGriff

Проблема в том, что если вы не следуете за книгой или курсом довольно внимательно, вы не улавливаете деталей - а такого рода "струнная" проблема довольно проста - я бы ожидал ее во второй или третьей главе большинства книг.
И "видеть, как это решается" на самом деле ничему вас не учит - вы не понимаете, почему это так, какие еще варианты были и почему они были отброшены. Все, что вы получаете, - это "свершившийся факт", который дает вам "решение" без какого-либо контекста, чтобы сказать: "Так вы всегда должны это делать". И я, вероятно, мог бы придумать полдюжины других способов сделать это, если бы я добавил Linq и тому подобное, некоторые из которых были бы "лучшим решением" для немного других сред или условий. Делая это самостоятельно, вы научитесь гораздо большему!

В любом случае: с какой частью вы боролись? Как далеко вы ушли?

Member 12714658

Вы абсолютно правы. Я согласен с вами. Я подумываю записаться на занятия этой осенью. Я попытался решить ее, используя свой подход с помощью функций, которые я написал. (Это совершенно неправильно?) поэтому я делаю foreach (string sentence in sentences){ then what then... я борюсь здесь. Может быть, я недостаточно абстрактно мыслю. или я должен использовать цикл for, чтобы я мог установить первый, чтобы быть самым большим = предложения[0]; как я проверяю каждое предложение, используя мои функции? а потом сравнить. Это может быть легко, но я этого не вижу.

OriginalGriff

Что ж...подсчет слов тривиален: вы разделили предложение на слова, да? Таким образом, количество слов-это количество элементов в вашем массиве слов...а массив имеет свойство длины! :смеяться:
А количество персонажей? Также тривиально-строка также имеет свойство длины, которое говорит вам, сколько символов она содержит!

Member 12714658

Как вы сказали, вы могли бы придумать десятки способов решить эту проблему. Дайте мне одно решение этой проблемы, тогда я буду знать, по крайней мере, один способ ее решения.

OriginalGriff

Ну, я уже дал вам один-все, что вам нужно, это собрать его вместе и организовать их.
Разделите входные данные на предложения.
Разбейте каждое предложение на слова и отсортируйте их.

Затем напишите метод под названием "Compare", который принимает две" коллекции слов "в качестве параметров и возвращает целое число: -1-Это первое" выше", чем второе, ноль, если они одинаковы, и 1, если второе" выше", чем первое.
Временно сравните первое слово каждого предложения, чтобы проверить свою структуру.
Затем напишите метод сортировки, который использует метод сравнения для организации коллекций слов - это базовый материал, он не должен быть сложным, подойдет пузырьковая сортировка (или вы можете использовать Linq, если понимаете лямбды).
Когда фреймворк работает, отредактируйте метод сравнения, чтобы сначала проверить количество дубликатов, затем количество слов, если два предложения имеют одинаковое количество дубликатов, а затем количество символов, если они имеют одинаковое количество слов.

Есть ли в этом смысл?

DimitriStPi

Не могли бы вы осмелиться проверить мой ответ ?

Member 12714658

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

DimitriStPi

Проверь сейчас, лучше не придумаешь. Запишите это как ответ, если это вам поможет. Спасибо!
И все же я здесь, чтобы объяснить, если вам это нужно.

Member 12714658

Спасибо за ваше время, я действительно ценю это. И я обдумаю все, что вы мне сказали. Еще раз спасибо!

OriginalGriff

Пожалуйста!