Program sprawdza ile w wyrazów w jednym pliku jest takich samych jak w drugim

0

Cześć mam problem z zadaniem. Mam do napisania program który sprawdza czy w tekście znajduje się szukany wyraz. Należy do tego wykorzystać pętle. Potem napisać metodę która korzysta z poprzedniej funkcji i na tej podstawie sprawdza ile wyrazów z pliku "wyrazy" znajduje się w pliku "plik".

Oto mój kod:

To jest napisane w "Class Library":

 public static bool czyIstnieje(string tekst, string wyraz)
        {
            int ile = 0;
            char[] t = tekst.ToCharArray();
            char[] w = wyraz.ToCharArray();
            int i = 0;
            while (i < t.Length - w.Length + 1)
            {
                int suma = 0;
                for (int j = 0; j < w.Length; j++)
                {
                    if (t[i + j] == w[j]) suma++;
                }
                if (suma == wyraz.Length) ile++;
                i++;
            }
            if (ile > 0) return true;
            return false;
        }
        public static int SprawdzPlik(string plik, string wyrazy)
        {
            string dane = zPliku(plik);
            string[] wyrazy_lista = wyrazy.Split(' ');
            int licznik = 0;
            for (int i = 0; i < wyrazy_lista.Length-1; i++)
			{
                if(czyIstnieje(dane, wyrazy_lista[i]))
                {
                    licznik++;
                }
			}
            return licznik;
        }
        public static string zPliku(string plik)
        {
            string w = string.Empty;
            StreamReader sr = new StreamReader(plik);
            while (!sr.EndOfStream)
            {
                w += sr.ReadLine();
            }
            sr.Close();
            return w;
        }
         

A to jest napisane w "Console Application":

static void Main(string[] args)
        {            
            Console.WriteLine(Operacje.czyIstnieje("Ala ma kota", "ma"));
            Console.WriteLine(Operacje.SprawdzPlik("wyrazy.txt", "plik.txt"));
            Console.ReadKey();
        } 

Na potrzeby programu w folderze gdzie znajduje się program stworzyłem dwa pliki tekstowe "wyrazy" i "plik" wpisałem do nich to samo, liczby, słowa, ze spacją, bez i dalej pokazuje 0. Czy program to źle wyświetla czy jednak są błędy w kodzie? Bo nie wiem co mam dalej z tym zrobić.

2

Nie wiem czy dokładnie o to chodziło ale możesz zrobić tak:

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

namespace App
{
    static class Ext
    {
        public static bool ContainsWord(this string phrase, string word)
        {
            return phrase.IndexOf(word) != -1;
        }

        public static int HowManyWordsIn(this FileInfo first, FileInfo second)
        {
            var firstContent = File.ReadAllText(first.Name).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToList();
            var secondContent = File.ReadAllText(second.Name);

            var count = 0;
            for (int i = 0; i < firstContent.Count; i++)
            {
                if (secondContent.ContainsWord(firstContent[i]))
                {
                    count += 1;
                    secondContent = secondContent.Remove(secondContent.IndexOf(firstContent[i]), firstContent[i].Length);
                    i = 0;
                }
            }
            return count;
        }

    }

    class Program
    {
        static void Main(string[] args)
        {
            var first = new FileInfo("wyrazy.txt");
            var second = new FileInfo("plik.txt");

            Console.WriteLine(first.HowManyWordsIn(second));
        }
    }
}

wyrazy.txt

grzesiek51114 szarotka somekind dibbbydum szarotka azarien

plik.txt

szarotka auto moto azarien szarotka moto grzesiek51114

Niepotrzebnie w swoim programie robisz jakieś zamiany na tablicę char'ów etc...

0

Zapomniałem dodać najważniejszego. Aby rozwiązać do zadanie bez Contains lecz za pomocą pętli. Bardzo dziękuję za tego typu rozwiązanie. Zachowam je sobie na przyszłość. Jednak chciałbym wiedzieć w jaki sposób mogę zrobić to bez tego.

2

zadanie ktore masz (tresc) jest absurdalna. Z jezyka C# kaza Ci pisac jakbys mial C

Jakbys popatrzyl uwaznie, to Grzesiek uzyl containsWord ktore sam zaimplementowal ;)

a to zadanie powinno byc rozwiazane w paru linijkach (samo sprawdzanie da sie zrobic w jednej za pomoca linq)

jezeli tez nie mozesz uzyc indexOf to zajrzyj tutaj
https://en.wikipedia.org/wiki/String_searching_algorithm

0

Jak skopiowałem ten program do siebie to nie wiem czemu ale mi nie odpalał, poza tym zwroty/frazy które są tutaj użyte są dla mnie trudne, typu IndexOf, var firstContent, StringSplit Options itp. itd. Tak możecie napisać że równie dobrze mogę sobie to posprawdzać jednak jak na obecną chwilę jestem w stanie powiedzieć że tego typu formuły nie są mi potrzebne bo ich nie używaliśmy. To są początki u mnie z tym językiem i jak widzę coś takiego + w jaki sposób mam to interpretować to mam mętlik w głowie. Dlatego proszę o prostsze, bardziej przejrzystą pomoc w rozwiązaniu.

0

Nie odpalił Ci się, bo chcesz z niego zrobić DLL'kę. Utwórz projekt konsolowy, a nie class library.

2

Wyjaśniony trochę kod @grzesiek51114, tu na prawdę nie ma nic trudnego;

public static bool ContainsWord(this string phrase, string word)
        {
            return phrase.IndexOf(word) != -1; // IndexOf zwraca miejsce w którym położona jest pierwsza litera danego słowa w stringu, przykładowo
            // "abcd".IndexOf("cd") zwróci 2, ponieważ programiści liczą od 0, jeśli dane słowo nie występuje zwracany jest -1
        }
 
        public static int HowManyWordsIn(this FileInfo first, FileInfo second)
        {
            var firstContent = File.ReadAllText(first.Name) // czytamy tekst z pliku
                       .firstContent.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) // Split powoduje zamianę stringa na tablicę stringów oddzielając słowa zadanym parametrem, w tym przypadku spacją, dodatkowy parametr StringSplitOptions.RemoveEmptyEntries, oznacza jak sama nazwa wskazuje usunięcie z tablicy pustych stringów jeśli takie się znajdą
            // przykład "a,b,c,d".Split(",") zamieni stringa na tablicę { "a", "b", "c", "d"}
                       .firstContent.Distinct() // powoduje usunięcie powtarzających się elementów z kolekcji czyli z { "a", "b", "c", "c", "d"} zrobi{ "a", "b", "c", "d"}
                       .firstContent.ToList(); // wcześniejszy distinct zwraca nie tablicę tylko kolekcję typu IEnumerable<string> (taka prostsza lista), używamy ToList aby zamienić to na List<string> aby później można było odwoływać się do itemu po indeksie czyli zrobić firstContent[i], równie dobrze możnaby tu użyć ToArray
            var secondContent = File.ReadAllText(second.Name);
            // var to jest tylko taki zamiennik dla typu zmiennej, mogło by być int count = 0; lub string dupa = "tekst";
            var count = 0;

Mam nadzieję że coś rozjaśniłem, a ten kod i tak jest prosty, naprawdę c# pozwala zrobić to zadanie w kilku linijkach używając linq.

0

Bardzo dziękuję za wytłumaczenie tego kodu. Jednak mimo tego że wiem jak go interpretować, raczej nie jestem w stanie go wykorzystać do rozwiązania innych zagadnień. Na tym etapie jest to dla mnie za trudne.

A czy jest jakiś sposób by to działało w bibliotece dll? No i poza tym czy można to napisać to w taki sposób w jaki pisałem na początku tego posta? Głównie taki zapis mnie interesuje.

0
Jumpeq napisał(a)

A czy jest jakiś sposób by to działało w bibliotece dll?

Zwyczajnie zaimplementuj jedynie klasy, bez funkcji main i skompiluj. Zamiast exec'a pojawi Ci się w bin'ie DLL'ka, którą dołóż jako referencję do projektu, który np. będzie korzystał z Twoich klas.

Jumpeq napisał(a)

No i poza tym czy można to napisać to w taki sposób w jaki pisałem na początku tego posta?

Generalnie wszystko można tylko to jest tak jak napisał @fasadin - po co pisać jak w latach 80'tych skoro masz na wyciągnięcie ręki nowoczesne i ergonomiczne rozwiązania? Ja wiem, że pewnie wykładowca czy tam ćwiczeniowiec kazał ale wykorzystując nowoczesne mechanizmy w takim zadaniu tylko u niego zaplusujesz. No chyba, że to jakiś facet, który dalej mentalnie siedzi w programowaniu we wspomnianych latach :)

0

Metody skopiowałem do biblioteki dll a jak do maina wsadzę:

 var first = new FileInfo("wyrazy.txt");
            var second = new FileInfo("plik.txt");

            Console.WriteLine(first.HowManyWordsIn(second));
            

To w ogóle się nie kompiluje, a nie wiem co ja mogę tu pozamieniać.

Korzystamy z takich metod/zapisów aby zrozumieć działania programów. Z tego co jest wyżej w poście napisane potrafię to przetworzyć i zastosować w innych projektach, bo wiem na czym bazować. Owszem mogę mu wysłać zadanie rozwiązane w taki sposób. Podejrzewam że raczej nie miałby nic przeciwko tylko pytanie.. po co skoro nie umiem tego nigdzie zastosować? I bardziej wolę się skupić na podstawowych metodach z którymi i tak mam problemy niż na siłę wysyłać projekty tego typu.

0

http://stackoverflow.com/questions/12992286/how-to-add-a-dll-reference-to-a-project-in-visual-studio
https://msdn.microsoft.com/en-us/library/wkze6zky.aspx

Oczywiście żeby to zadziałało należy dołożyć za pomocą using przestrzeń nazw taką jaką masz w klasach z DLL'ką. Jest to zresztą napisane w pierwszym linku:

From there you can reference dll's, after which you can reference namespaces that you need in your code.

0

Tak, mam to dołożone ale nie działa, nie odczytuje mi maina mam nast. komunikaty:
"Error 3 The type or namespace name 'FileInfo' could not be found (are you missing a using directive or an assembly reference?) C:\Users\User\Documents\Visual Studio 2012\Projects\Próbbna8domowa\ConsoleApplication1\Program.cs 21 29 ConsoleApplication1
"Error 4 The type or namespace name 'FileInfo' could not be found (are you missing a using directive or an assembly reference?) C:\Users\User\Documents\Visual Studio 2012\Projects\Próbbna8domowa\ConsoleApplication1\Program.cs 22 30 ConsoleApplication1
"
A to już w bibliotece
"Error 1 Extension method must be defined in a non-generic static class C:\Users\User\Documents\Visual Studio 2012\Projects\Próbbna8domowa\Biblioteka\Class1.cs 10 18 Biblioteka
"
naprawde nie wiem o co chodzi

0

Zrób tak jak w załączniku.

0

Mam zrobione identycznie jednak problemy są chyba z frameworkami
Coś takiego mi wywala:
Error 1 The type or namespace name 'MyDLL' could not be found (are you missing a using directive or an assembly reference?) C:\Users\User\Downloads\MyProgram\MyProgram\MyProgram\Program.cs 7 7 MyProgram

i
Warning 2 The primary reference "MyDLL, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL" could not be resolved because it was built against the ".NETFramework,Version=v4.6.1" framework. This is a higher version than the currently targeted framework ".NETFramework,Version=v4.5". MyProgram

Mam Visual Studio 2012 Ultimate

0

Ustaw Target Framework na jednakową wersję w obu projektach, przekompiluj i spróbuj ponownie. Ustawiasz to we właściwościach każdego projektu.

0

Dopiero po ustawieniu frameworka na 6.2 program się uruchamia jednak nie działa właściwie. Kiedy uruchamiałem go w konsoli podawało prawidłową liczbę ile wyrazów się znajduje, teraz pokazuje 1 albo 0, i to 0 nawet wtedy kiedy są wyrazy tyle że w innej kolejności.
Poza tym nie bardzo widzę sens rozwodzić się nad tym kodem bo "nie czuję go" wolałbym coś w stylu co napisałem na początku.

I tak à propos, jest tutaj na forum możliwość włączenia jakiegoś powiadomienia kiedy ktoś odpisze na mój post albo który obserwuję? Bo tak naprawde losowo sprawdzam czy ktoś odpisał czy też nie. Wyświetlają mi się jedynie komunikaty jak ktoś skomentuje to co napisałem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1