x-kom hosting

ilość powtórzeń wyrazu w łańcuchu [java]

student878
utworzono
utworzono

Witam, potrzebuję pomocy. Nie wiem jak napisać taki program który by podawał ilość powtórzonego wyrazu w łańcuchu. (Np w zdaniu "Ala ma kota a kot ma ale" trzeba podać ilość wystąpień słowa "ma", czyli tutaj 2 razy).  proszę o jakieś podpowiedzi. pozdrawiam:)

leggo
komentarz
komentarz

Jeśli nie zależy Ci na jakichś "wyszukanych" sposobach typu rekurencja, wystarczy, że w pętli przeszukasz cały łańcuch i policzysz ile razy litera [i]a[/i] występuje bezpośrednio po [i]m[/i].

Jeżeli szukasz tyko wyrazów (a nie fragmentów wyrazów), musisz jeszcze upewnić się, że w bezpośrednim sąsiedztwie tych liter występują tylko znaki interpunkcyjne lub białe.

 

Jeśli będziesz miał jeszcze jakieś wątpliwości wstaw tutaj fragment kodu, który uda Ci się do tego czasu napisać.

  • Dobra wypowiedź 1
student878
komentarz
komentarz
Jeśli nie zależy Ci na jakichś "wyszukanych" sposobach typu rekurencja, wystarczy, że w pętli przeszukasz cały łańcuch i policzysz ile razy litera a występuje bezpośrednio po m.

Jeżeli szukasz tyko wyrazów (a nie fragmentów wyrazów), musisz jeszcze upewnić się, że w bezpośrednim sąsiedztwie tych liter występują tylko znaki interpunkcyjne lub białe.

 

Jeśli będziesz miał jeszcze jakieś wątpliwości wstaw tutaj fragment kodu, który uda Ci się do tego czasu napisać.

 

import java.util.Scanner;
import java.util.StringTokenizer;
 
import javax.swing.JOptionPane;
 
 
public class zaddwa {
 
private static String[] tablica; 
 
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String tekst = JOptionPane.showInputDialog("Wpisz tekst...");
StringTokenizer st = new StringTokenizer(tekst, " \t\n\r\f.,:;()[]\"'?!-{}");
int n = st.countTokens();  
tablica = new String[n];      
tablica[0] = st.nextToken();
 
while (st.hasMoreTokens()) 
{   
     String s = st.nextToken();
}
 
for (int i =0;i<tablica.length;i++)
{
 
}
 
}
 
}
chodzi mi o całe wyrazy..jestem na tym etapie i się zastanawiam co wpisać w pętlę   if(tablica[0]="ma")? możesz podpowiedzieć i sprawdzić czy to co napisałem jest dobrze?
rafalluz
komentarz
komentarz

W javie sprawa jest o tyle prosta, że masz odpowiednią metodę substring w klasie String. Możesz wyciągnąć substring z pozycji od 1 to n-2 i sprawdzić, czy jest on równy "ma".

 

http://www.tutorialspoint.com/java/java_string_substring.htm

leggo
komentarz
komentarz

[quote name='student878' timestamp='1358005475' post='1671997'] if(tablica[0]="ma") [/quote]

Nie możesz w taki sposób porównywać (pomijając fakt, że to w ogóle nie jest porównanie). Pod [b]tablica[0][/b] znajduje się jeden znak, a [b]"ma"[/b] to łańcuch znaków. A więc są to wartości różnych typów.

Dodatkowo do porównywania wartości używa się podwójnego znaku równości ([b]==[/b]).

student878
komentarz
komentarz
W javie sprawa jest o tyle prosta, że masz odpowiednią metodę substring w klasie String. Możesz wyciągnąć substring z pozycji od 1 to n-2 i sprawdzić, czy jest on równy "ma".

 

http://www.tutorialspoint.com/java/java_string_substring.htm

no tak ale jeżeli jest też na innych pozycjach nieznanych to już tego nie sprawdzę i nie pomoże mi to do określenia ilości powtórzeń 

rafalluz
komentarz
komentarz

Ale nikt nie powiedział, że masz tą funkcję wywołać dokładnie raz ;)

student878
komentarz
komentarz
Nie możesz w taki sposób porównywać (pomijając fakt, że to w ogóle nie jest porównanie). Pod tablica[0] znajduje się jeden znak, a "ma" to łańcuch znaków. A więc są to wartości różnych typów.

Dodatkowo do porównywania wartości używa się podwójnego znaku równości (==).

no tak nie dopisałem drugiego =...chyba się mylisz wpisz sobie System.out.println(tablica[0]); i Ci poda pierwszy ciąg znaków do spacji...nadal się nad tym głowie i nic:/

sigmaPi
komentarz
komentarz (edytowane)
Nie możesz w taki sposób porównywać (pomijając fakt, że to w ogóle nie jest porównanie). Pod tablica[0] znajduje się jeden znak, a "ma" to łańcuch znaków. A więc są to wartości różnych typów.
Dodatkowo do porównywania wartości używa się podwójnego znaku równości (==).

W Javie zawartość stringów powinno porównywać się wyłącznie za pomocą funkcji equals(String) z klasy String, wywoływanej na rzecz jednego z nich. Operator == porównuje obiekty bazując na ich adresie w pamięci.

Przykład obrazujący dlaczego w tym przypadku nie powinno się używać operatora ==:

[code]import javax.swing.*;
public class Program {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String a="abc";
        String b=JOptionPane.showInputDialog("Wyraz:");
        testEquals(a,b);
        testOperator(a,b);
        System.exit(0);
    }
    private static void testEquals(String a, String b){
        if(a.equals(b))
            System.out.println("EQUALS: A jest równe B");
        else
            System.out.println("EQUALS: A nie jest równe B");
    }
    private static void testOperator(String a, String b){
        if(a==b)
            System.out.println("OPERATOR: a==b");
        else
            System.out.println("OPERATOR: a!=b");
    }

}[/code]

Po wpisaniu do inputDialoga ciągu znaków abc rezultatem działania programu będzie:

[code]EQUALS: A jest równe B
OPERATOR: a!=b
[/code]

A więc zawierzając w tym przypadku operatorowi, otrzymałbyś błędny wynik.

Edytowane przez sigmaPi
  • Dobra wypowiedź 1
student878
komentarz
komentarz
czyli coś takiego, a jak obliczyć teraz ilość wykonań instrukcji warunkowej? czy jest jeszcze jakiś inny sposób? 
for (int i =0;i<tablica.length;i++)
{
if("ma".equals(tablica[i]));
{
 
}
}
sigmaPi
komentarz
komentarz

W powyższym kodzie masz błąd. Nie powinno być:

[code]if("ma".equals(tablica[i]))[/code]

tylko odwrotnie:

[code]if(tablica[i].equals("ma"))[/code]

 

Wracając jednak do pytania. Nie musisz tego obliczać. Istnieje specjalny rodzaj pętli FOR kończącej działanie zaraz po osiągnięciu ostatniego elementu danej struktury danych.

Poniżej przykład, który mam nadzieję nieco Ci pomoże:

[code]        int result=0;
        String[] table={"Ala","ma","kota",",","a","kot","ma","Alę"};
        for(String word: table)
            if(word.equals("ma"))
                result++;
        System.out.println("Ilość wystąpień: "+result);[/code]

  • Dobra wypowiedź 1
leggo
komentarz
komentarz

Tak, tylko najpierw trzeba tego string-a podzielonego wsadzić do tablicy. Można do tego użyć [b]split[/b] i dzielić po spacji, ale wtedy trzeba by było się jeszcze pozbyć z ciągu znaków interpunkcyjnych.

sigmaPi
komentarz
komentarz (edytowane)

Tu nawet nie potrzeba tablic i pętli for (nawet tej rozszerzonej). Wystarczy użyć StringTokenizer (z odpowiednio ustawionymi znakami rozdzielającymi) i jednej pętli while. Student878 był na dobrym tropie na początku tego tematu.

Chyba, że w treści zadania jest jeszcze coś, o czym nie wiemy. Gdyby bowiem chodziło o podanie ilości wystąpień określonego ciągu znaków (a nie wyrazu), np. sklejonego z innymi wyrazami, to sytuacja miałaby się zgoła inaczej.

Edytowane przez sigmaPi
leggo
komentarz
komentarz

[quote name='sigmaPi' timestamp='1358027212' post='1672376'] Wystarczy użyć StringTokenizer [/quote]

Wydaje się, że to cudo całkowicie rozwiązuje problem.

sigmaPi
komentarz
komentarz

Raczej tak.

Ponieważ StringTokenizer bierze pod uwagę rozmiar liter, można jeszcze przed porównywaniem pokusić się o konwersję całego zdania, jak i wpisywanego przez użytkownika wyrazu, do wielkich lub małych liter. Dzięki temu wyrazy takie jak "Ma", "MA" czy "ma" również zostaną uwzględnione.

student878
komentarz
komentarz
Raczej tak.

Ponieważ StringTokenizer bierze pod uwagę rozmiar liter, można jeszcze przed porównywaniem pokusić się o konwersję całego zdania, jak i wpisywanego przez użytkownika wyrazu, do wielkich lub małych liter. Dzięki temu wyrazy takie jak "Ma", "MA" czy "ma" również zostaną uwzględnione.

 

import java.io.IOException;
import java.util.Scanner;
import java.util.StringTokenizer;
 
import javax.swing.JOptionPane;
 
public class zaddwa {
 
 
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String tekst = JOptionPane.showInputDialog("Wpisz tekst...");
StringTokenizer st = new StringTokenizer(tekst," ");
st.nextToken(" ");
int n = st.countTokens(); 
 
while (st.hasMoreTokens()) 
{   
     String s = st.nextToken();
}
 
int result=0;
String[] tablica = new String[n];    
for (String word: tablica  )
{
if(word.equals("ma"))
{
result++;
}
System.out.println("ilość wystąpień "+result);
}
}
}
co tutaj źle napisałem? program się kompiluje ale wyskakuje błąd gdy wpisuje tekst i wskazuje na linię z instrukcją warunkową:/


Raczej tak.

Ponieważ StringTokenizer bierze pod uwagę rozmiar liter, można jeszcze przed porównywaniem pokusić się o konwersję całego zdania, jak i wpisywanego przez użytkownika wyrazu, do wielkich lub małych liter. Dzięki temu wyrazy takie jak "Ma", "MA" czy "ma" również zostaną uwzględnione.

 

import java.io.IOException;
import java.util.Scanner;
import java.util.StringTokenizer;
 
import javax.swing.JOptionPane;
 
public class zaddwa {
 
 
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String tekst = JOptionPane.showInputDialog("Wpisz tekst...");
StringTokenizer st = new StringTokenizer(tekst,"/ ");
st.nextToken(" ");
int n = st.countTokens(); 
String[] tablica = new String[n];
int i=0;
while (st.hasMoreTokens()) 
{   
 tablica[i] = st.nextToken();
    i++;
}
 
int result=0;
   
for (String word: tablica  )
{
if(word.equals("ma"))
{
result++;
}
 
}
System.out.println("ilość wystąpień "+result);
}
}
z tablica miałem źle ale nadal jest trochę źle bo jak wpisuję "ma" to program pokazuje 0 i nie wiem czemu a tak to jest juz dobrze 
sigmaPi
komentarz
komentarz

Oj, straszny masz bałagan w kodzie.
Program pokazuje Ci, że nie masz wystąpień słowa "ma" po w pisaniu w input dialog, ponieważ napisałeś go w taki sposób, że użytkownik musi wpisać [b]zdanie[/b], w którym hardcode'owane (czyli osadzone w kodzie) "ma" będzie wyszukiwane. Czyli na odwrót niż chyba planowałeś. :)
Użytkownik powinien raczej podawać jakiego wyrazu szuka w zdaniu, albo podaje i zdanie i wyraz w dwóch input boxach.

Dodatkowo: [u]nazwy klas zawsze zaczyna się wielką literą[/u]. Dobrą praktyką jest także, jeżeli nazwa klasy/zmiennej/metody/funkcji, etc. składa się z kilku wyrazów, zaczynać kolejne wielką literą. A zatem nie "zaddwa", tylko "ZadDwa".

[code]import java.io.IOException;
import java.util.Scanner;[/code]
Niepotrzebne.
[code]Scanner in=new Scanner(System.in);[/code]
Kompletnie zbędne. Nigdzie tego nie wykorzystujesz. Poza tym, raz otwarty strumień trzeba zamykać gdy już nie jest potrzebny.
[code]String tekst=JOptionPane.showInputDialog("Wpisz tekst...");[/code]
OK.
[code]StringTokenizer st = new StringTokenizer(tekst,"/ ");
st.nextToken(" ");
int n = st.countTokens();
[/code]
Tutaj jest jakiś bałagan. Przeczytaj dokładnie w JavaDoc (http://docs.oracle.com/javase/7/docs/api/) do czego służy i jak używać klasy StringTokenizer (http://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html).
Skoro zdecydowałeś się z niej skorzystać, powinieneś wiedzieć o niej możliwie jak najwięcej. Z jakich konstruktorów korzystać, jak poprawnie określić znaki rozdzielające poszczególne tokeny, itp.

[code]StringTokenizer st = new StringTokenizer(tekst,"/ ");[/code]
Konstruktor StringTokenizer(String str, String delim) jako drugi argument przyjmuje stringa zawierającego znaki, które chcesz aby użyte były jako znaki rozdzielające. Domyślnie znakami tymi są:
[quote]" \t\n\r\f": the space character, the tab character, the newline character, the carriage-return character, and the form-feed character.[/quote]
Powinieneś więc użyć czegoś w stylu: ",. \t\n\r\f" jeśli dodatkowo chcesz zawrzeć np. kropkę i przecinek. Nie wiem co miałeś na myśli ustawiając jako delimiter (abstrahując od spacji - to jest ok) także znak "/".
[code]st.nextToken(" ");[/code]
Przesuwa wskaźnik na kolejny wyraz, traktując "spację" jako znak rozdzielający. Zupełnie niepotrzebne w tym miejscu. Na dodatek linia jest zmarnowana, bo nie wykonujesz na niej żadnej operacji (np. przyrównania) a wskaźnik zostaje przesunięty na kolejne słowo, więc pierwsze jest bezpowrotnie tracone.
[code]int n=st.countTokens();[/code]
Nie jest nam potrzebna informacja o ilości wyrazów w zdaniu.
[code]int i=0;
while (st.hasMoreTokens()){   
    tablica[i] = st.nextToken();
    i++;
}[/code]
Pętla while i jej warunek (czyli "wykonuj dopóki w zdaniu są jeszcze wyrazy") jest OK. Jej zawartość? Można i tak, ale jeśli wykorzystujesz tablicę, to od razu w tym przypadku podwaja się ilość operacji porównania, ponieważ potem znowu porównujesz w drugiej pętli elementy tablicy do ciągu znaków "ma".
Można tutaj obejść się bez tablicy i wszystko od razu zrobić w pętli while.

Na koniec jeszcze trzeba zadać sobie pytanie na jakim etapie jesteście obecnie w programowaniu. To jest ważne, ponieważ może takie zadanie macie zrobić tylko w oparciu o tablice, a nie inne klasy? Pamiętam, że myśmy kiedyś też takie coś robili (to chyba dyżurne zadanie na każdej uczelni i też nawet było "Ala ma kota"), ale to było zdaje się przed klasami.

Wciąż szukasz rozwiązania problemu? Napisz teraz na forum!

Możesz zadać pytanie bez konieczności rejestracji - wystarczy, że wypełnisz formularz.

×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Strona wykorzystuje pliki cookies w celu prawidłowego świadczenia usług i wygody użytkowników. Warunki przechowywania i dostępu do plików cookies możesz zmienić w ustawieniach przeglądarki.