Toon posts:

[java] alfabet in een bitset zetten

Pagina: 1
Acties:
  • 165 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
ik moet voor een opdracht, het alfabet in een bitzet zetten. Om nu alle letter appart te gaan declareren lijkt me nogal een omslachtig iets, bestaat er geen snellere manier in java om het alfabet in een bitset te zetten? kan niets in mijn book of op het web vinden :(

  • JnX
  • Registratie: Februari 2001
  • Laatst online: 18-01 22:08

JnX

Ik weet niet precies wat jij bedoelt met een bitset, maar om het hele alfabet te doorlopen kan je een while loop gebruiken.

Je kan namelijk een char met 1 verhogen om naar de volgende letter in het alfabet (de ASCI tabel eigenlijk) te gaan. Dus:

char bla = 'a';
bla++;

Nu bevat bla de letter 'b'. Op deze manier kan je met een while-loop het hele alfabet doorlopen (stoppen wanneer bla = 'z'.

[ Voor 18% gewijzigd door JnX op 24-02-2005 11:50 ]


Verwijderd

Topicstarter
ik denk dat bitset misschien bekender is onder het woord set?
in ieder geval een datastructuur waarin alleen unieke elementen voorkomen

het idee van het programma is het volgende:

je voert een zin in, en vervolgens gaat hij checken welke letter er wel voorkomen en welke letter niet voorkomen in de zin

[ Voor 39% gewijzigd door Verwijderd op 24-02-2005 11:55 ]


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Ergo, JnX's oplossing gebruiken:
Initialisatie van de bitset dmv een methode waarin je met een for-loop alle letters in de set plaatst.
Vervolgens de zin letter voor letter in een nieuwe set plaatsen (zoals in je vorige topic ;) ). Tenslotte een doorsnede om te zien welke letters voorkomen (zodat spaties, getallen etc eruit worden gefilterd) en een omgekeerde doorsnede (geef alle elementen uit set A die niet in set B voorkomen, zul je moeten schrijven denk ik).

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

Je kunt toch ook gewoon een bool array van 26 elementen nemen?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
JnX schreef op donderdag 24 februari 2005 @ 11:48:
Ik weet niet precies wat jij bedoelt met een bitset, maar om het hele alfabet te doorlopen kan je een while loop gebruiken.

Je kan namelijk een char met 1 verhogen om naar de volgende letter in het alfabet (de ASCI tabel eigenlijk) te gaan. Dus:

char bla = 'a';
bla++;

Nu bevat bla de letter 'b'. Op deze manier kan je met een while-loop het hele alfabet doorlopen (stoppen wanneer bla = 'z'.
zoiets?
code:
1
2
3
4
5
char l
            for (l='a';l=<'z' ;l++ )
            {
            System.out.println(l);
            }


dit gaat WEL werken inderdaad

[ Voor 7% gewijzigd door Verwijderd op 24-02-2005 12:07 ]


Verwijderd

Topicstarter
bigbeng schreef op donderdag 24 februari 2005 @ 12:01:
Ergo, JnX's oplossing gebruiken:
Initialisatie van de bitset dmv een methode waarin je met een for-loop alle letters in de set plaatst.
Vervolgens de zin letter voor letter in een nieuwe set plaatsen (zoals in je vorige topic ;) ). Tenslotte een doorsnede om te zien welke letters voorkomen (zodat spaties, getallen etc eruit worden gefilterd) en een omgekeerde doorsnede (geef alle elementen uit set A die niet in set B voorkomen, zul je moeten schrijven denk ik).
bedankt voor het idee, was ook precies mijn plan zoals jij het nu omschrijft, nu nog ff uitprogrammeren... je kunt nog wel wat vraagjes verwachten vandaag :)

Verwijderd

Topicstarter
woorden komen in args dus die worden al netjes gesplit, maar hoe split ik de woorden op in letters? is daar een standaard functie voor?

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Strings kun je heel eenvoudig omzetten naar char arrays. Even door de documentatie pluizen.

Weet je wat, ik geef je alvast een hint: toCharArray(), mag jij raden van welke Class dit een method is :)

Verwijderd

Topicstarter
ik heb het volgende

code:
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
import java.util.*;

public class letters

{
    public static void main(String[] args) 
    {
        char l;
        BitSet alfabet = new BitSet(26);
        

            for (l='a';l<='z';l++ )
            {
            alfabet.set(l);
            System.out.println(l);

            }
        
        int xl = args.length;
        int x;
        System.out.println(xl);
        BitSet invoer = new BitSet(x);

        for (x=0;x<xl ;x++ )
        {
        System.out.println(args[x]);
                                // het volgende lijkt me niet goed
        invoer.set(args[x].split(.));

        }

            
        
    }
}


bij //het volgende... lijkt me het niet goed gaan, ik wil het woord als element in args splitten op letterbasis en vervolgende in de set invoer zetten, dit mag zo niet of wel? hoe moet het wel?

Verwijderd

Topicstarter
bigbeng schreef op donderdag 24 februari 2005 @ 12:47:
Strings kun je heel eenvoudig omzetten naar char arrays. Even door de documentatie pluizen.

Weet je wat, ik geef je alvast een hint: toCharArray(), mag jij raden van welke Class dit een method is :)
ja die had ik al gevonden :) maar dacht misschien dat het sneller kan want ik moet die chararray weer omzetten naar een set..

en ik heb ook nooit eerder met toCharArray gewerkt,

kan ik een array maken x
en zeggev van string y
y.toCharArray(x)?

[ Voor 13% gewijzigd door Verwijderd op 24-02-2005 12:57 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

Hint: er bestaat ook een Afbeeldingslocatie: http://gathering.tweakers.net/global/templates/tweakers/images/icons/edit.gif-knop, maak er gebruik van! ;)

PS. deze reactie behoeft geen tegenreacte :)

[ Voor 18% gewijzigd door .oisyn op 24-02-2005 12:54 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 13-05 15:57

Robtimus

me Robtimus no like you

Verwijderd schreef op donderdag 24 februari 2005 @ 12:50:
ik heb het volgende

code:
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
import java.util.*;

public class letters

{
    public static void main(String[] args) 
    {
        char l;
        BitSet alfabet = new BitSet(26);
        

            for (l='a';l<='z';l++ )
            {
            alfabet.set(l);
            System.out.println(l);

            }
        
        int xl = args.length;
        int x;
        System.out.println(xl);
        BitSet invoer = new BitSet(x);

        for (x=0;x<xl ;x++ )
        {
        System.out.println(args[x]);
                                // het volgende lijkt me niet goed
        invoer.set(args[x].split(.));

        }

            
        
    }
}


bij //het volgende... lijkt me het niet goed gaan, ik wil het woord als element in args splitten op letterbasis en vervolgende in de set invoer zetten, dit mag zo niet of wel? hoe moet het wel?
BitSet.set kan geen array van string accepteren, maar alleen een int. Kijk verder op http://java.sun.com/j2se/...api/java/util/BitSet.html.

Hint:
Je BitSet heeft indeces van 0 t/m 25. Dat zijn dus de enige waarden die je mag gebruiken bij BitSet.set. Als char c een letter is, dan is c - 'a' de relatieve index vergeleken met een a.


Edit: nu ik er beter naar kijk gaat er wel meer mis. 'a' is nml groter dan je maximale index van 25 (regel 14). En je invoer BitSet heeft waarschijnlijk een lengte van 0 omdat je vergeet x te initialiseren.

[ Voor 13% gewijzigd door Robtimus op 24-02-2005 13:10 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Verwijderd schreef op donderdag 24 februari 2005 @ 12:51:
[...]


ja die had ik al gevonden :) maar dacht misschien dat het sneller kan want ik moet die chararray weer omzetten naar een set..

en ik heb ook nooit eerder met toCharArray gewerkt,

kan ik een array maken x
en zeggev van string y
y.toCharArray(x)?
http://java.sun.com/j2se/...String.html#toCharArray()
Er is maar 1 method toCharArray en die geeft een char array terug, dus:
y = x.toCharArray() // met y van type char[]
Chars kun je 1 op 1 omzetten naar ints, dus door je array loopen en dan per letter een toevoegactie doen. Lees anders de Java tutorial even door om te zien hoe je van chars ints kunt maken. Hint: dat heet typecasting. Je kunt dan eventueel ook de methode van IcemanX toepassen, als je dat zou willen.
Helaas vrees ik dat je het bovenstaande allemaal zelf zal moeten programmeren, maar dat is wel goed voor het algoritmisch programmeren, nietwaar? :P

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

Waarom per se een BitSet gebruiken als je ook gewoon een Set kunt gebruiken waar je gewoon characters in kunt stoppen?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
uit die alfabet bitset komen de getallen 97 t/m 122, dat klopt toch?

Verwijderd

Topicstarter
ik ben nu zover, hij zet het alfabet in een BitSet alfabet en de letters uit de opdrachtregel in een BitSet invoer, en vervolgens worden de elementen uit de bitset invoer uit de alfabet bitset gezet. echter ik zit nog met een probleempje:
ik moet de grootte van char[] z en BitSet[] invoer vooraf declareren, maar hoe weet ik hoe groot deze moet gaan worden? hoe zet ik die int's in de bitset nu weer om in characters? kan niets vinden op de java site

code:
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
36
37
38
39
40
41
import java.util.*;

public class letters

{
    public static void main(String[] args) 
    {
        char l;
        BitSet alfabet = new BitSet(26);
        String y;
        

            for (l='a';l<='z';l++ )
            {
            alfabet.set(l);
            System.out.println(l);
            }

            System.out.println(alfabet);
            
            

            char[] z = new char[100];
            int a;
            BitSet invoer = new BitSet(100);

            for (a=0;a<args.length ;a++ )
            {
            z = args[a].toCharArray();
            
                for (int b=0;b<z.length ;b++ )
                {
                System.out.println(z[b]);
                invoer.set(z[b]);
                alfabet.clear(z[b]);
                }
            }
            System.out.println(invoer); 
            System.out.println(alfabet);
    }
}

[ Voor 18% gewijzigd door Verwijderd op 24-02-2005 15:00 ]


  • Gert
  • Registratie: Juni 1999
  • Laatst online: 05-12-2025
Elke bit in de bit set is een index in het alfabet, aangezien het alfabet begint bij a is bit op positie 0, positie 1 is a+1 = b.

Dus als je wil kijken welke bits true zijn en dat omzetten naar letters doe je
code:
1
2
voor elke x tussen 0 en de lengte van de bitset
  als waarde van bitset is true dan letter is a + x

Waarom moet je de grootte van de bitset en de character array van te voren definieren?
Java:
1
2
3
4
5
6
7
8
9
10
11
12
char woord[];
int c;

for (int x = 0; x < args.length; x++) {
  woord = args[x].toCharArray();
  for (int y = 0; y < woord.length; y++) {
    c = a - woord[x];
    if (!alfabet.get(c)) {
      alfabet.flip(c);
    }
  }
}

[ Voor 6% gewijzigd door Gert op 24-02-2005 15:21 ]


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Volgens mij moet je met de API specs en wat doorzettingsvermogen nu toch wel verder komen. Mij bekruipt langzaam het gevoel dat je nu elke vraag die bij je opkomt hier gaat stellen, terwijl het meeste toch gewoon in de documentatie staat. Lees deze pagina eens aandachtig door, hiermee kun je je laatste vragen vrij eenvoudig zelf beantwoorden.

Ik moet trouwens zeggen dat ik zelf ook niet goed naar de BitSet specificaties heb gekeken, anders had ik gelijk gezegd dat de oplossing van IceManX de enige goede is.
Tenzij je natuurlijk van een BitSet mag afstappen en gewoon een TreeSet mag gebruiken.

Het makkelijke van bitsets is dat je and, or and xor operaties al standaard meekrijgt. Die hoef je dus niet zelf te schrijven.

En nou gewoon ff doorzetten, zo ingewikkeld is het allemaal niet :)

Verwijderd

Topicstarter
is inderdaad allemaal goed gelukt :)

ik kom alleen niet uit het decoderen van int naar char, oftewel van de codes naar letters

ik weet inmiddels dat je gewoon kunt zeggen

char ch = 97;

en dit zal opleveren a, echter wanneer ik zeg

int letter = 97;
char ch = letter;

geeft hij een compile error 'possible loss of precision'

--------------------------

al opgelost TYPE moet char zijn van letter en niet een INT

[ Voor 69% gewijzigd door Verwijderd op 24-02-2005 17:06 ]


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Ik had de hint al gegeven: Typecasting
Doe me nou een plezier en volg die basis tutorial Java gewoon even. Het kost niet veel tijd en geeft een behoorlijke basis. Antwoorden op dit soort vragen komen daarin aan bod.

Maar ik weet dat je graag verder wil, daarom: kijk naar het antwoord van IcemanX eerder in dit topic. Hij geeft het daar al weg. :)

edit:
Stiekum je post editen he :+

[ Voor 7% gewijzigd door bigbeng op 24-02-2005 17:09 ]


Verwijderd

Topicstarter
bedankt voor al jullie tips, het is het volgende code geworden uiteindelijk:

code:
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
36
37
38
39
40
41
import java.util.*;

public class LetterCounts{
    public static void main(String[] args){
        //declareer BitSet alfabet om alle letters uit het alfabet in op te slaan
        BitSet alfabet = new BitSet();
        //zet alle letter uit het alfabet in de BitSet
        for (char i='a';i<='z';i++ ){
            alfabet.set(i);
        }
        //declareer character array om letters uit invoer prompt in op te slaan
        char letters[];
        for (int i=0;i<args.length;i++ ){
            //zet de letters uit de invoerprompt in char array letters
            letters = args[i].toCharArray();
            //doorloop de array met letters en haal de in alfabet BitSet voorkomende letters uit de Bitset
            for (int j=0;j<letters.length ;j++ ){
                alfabet.clear(letters[j]);
            }
        }
        //strings waar letter voor printen in komen te staan        
        String used = new String();
        String missing = new String();
        //doorloop het alfabet
        for (char letter='a';letter<='z';letter++ ){
            //boolean om tydelijk op te slaan of element afwezig is in BitSet alfabet       
            boolean afwezig = alfabet.get(letter);
            //als afwezig false is, is letter wel gebruikt en zet deze letter vervolgens in de string used erbij
            if (afwezig==false){
                used = used + letter;
            }           
            //als afwezig true is, is letter niet gebruikt en zet letter vervolgens in string missing erbij
            if (afwezig==true){
                missing = missing + letter;
            }
        }
        //print de strings met antwoorden       
        System.out.println("Letters used: " + used);
        System.out.println("Letters missing: " + missing);
    } 
}

  • Macros
  • Registratie: Februari 2000
  • Laatst online: 30-04 09:28

Macros

I'm watching...

Nu je zelf al een oplossing heb gemaakt zal ik laten zien hoe het echt moet ;)
Java:
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
import java.util.BitSet;
/*
 * Created on 24-feb-2005
 */
public class LettersCount {
    public static void main(String[] args) {
        BitSet set = new BitSet(26);
        for(String word : args){
            word = word.toLowerCase();
            for(int i = 0; i < word.length(); i++){
                char c = word.charAt(i); 
                if(c >= 'a' && c <= 'z')
                    set.set(c-'a');
            }
        }
        StringBuilder in = new StringBuilder();
        StringBuilder out = new StringBuilder();
        for(char i = 0; i < 26; i++){
            if(set.get(i))
                in.append('a' + i);
            else 
                out.append('a' + i);
        }
        System.out.println("Letters used: " + in.toString());
        System.out.println("Letters not used: " + out.toString());
    }
}

[ Voor 7% gewijzigd door Macros op 24-02-2005 21:41 ]

"Beauty is the ultimate defence against complexity." David Gelernter


  • Macros
  • Registratie: Februari 2000
  • Laatst online: 30-04 09:28

Macros

I'm watching...

Nu met een boolean array, deze is eigenlijk beter, want dan zie jij wat je eigenlijk fout doet:
Java:
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
/*
 * Created on 24-feb-2005
 */
public class CharCount {
    public static void main(String[] args) {
        boolean[] set = new boolean[26];
        for(String word : args){
            word = word.toLowerCase();
            for(int i = 0; i < word.length(); i++){
                char c = word.charAt(i); 
                if(c >= 'a' && c <= 'z')
                    set[c-'a'] = true;
            }
        }
        StringBuilder in = new StringBuilder();
        StringBuilder out = new StringBuilder();
        for(char i = 0; i < 26; i++){
            if(set[i])
                in.append((char)('a'+i)); // cast nodig, anders denkt java dat het ints zijn
            else 
                out.append((char)('a'+i));
        }
        System.out.println("Letters used: " + in.toString());
        System.out.println("Letters not used: " + out.toString());
    }
}

[ Voor 17% gewijzigd door Macros op 24-02-2005 21:44 ]

"Beauty is the ultimate defence against complexity." David Gelernter


Verwijderd

Topicstarter
nou ik doe niets verkeerds, de opdracht was het mbv bitsets te bouwen :)

  • Macros
  • Registratie: Februari 2000
  • Laatst online: 30-04 09:28

Macros

I'm watching...

Oke, hier komt de theorie.
Je wilt opslaan welke letters er wel en niet zijn geweest. Hiervoor neem je de binaire kwaliteiten van het computergeheugen voor. Elk bit representeert de aanwezigheid van een letter aan in de opgegeven string. Je hebt dus een rij met bits, waarbij de eerste de 'a' representeert enz. tot de laatste, wat de 'z' representeerd. Je hebt dus 26 bits.
Normale manier omzoiets op te slaan zou een array zijn van bits. Helaas, computers werken met een minimum van 8, 16, 32 of 64 bits tegelijk. De afzonderlijke bits zijn niet direct te addreseren, dus neemt elk element in een bit/boolean array 8 of meer bits in beslag. Daarom heeft Java de BitSet, dit is gelijk aan een boolean array, alleen deze wordt automatisch groter als je hogere bits benaderd. Intern gebruikt deze long's en gebruikt bitmanipulatie om de afzondelijke bits in de array te addreseren. Dit neemt dus 8 keer zo weinig geheugen in, maar is wel trager. Een BitSet gebruik je dus om minder geheugen te gebruiken dan normaal.
Maar je begint halverwege de BitSet met het mappen van de letters van het alfabet, en hoofdletters map je op hun normale plek, maar je controleert er later niet op. De 'a' zou op plek 0 moeten in de set, en niet op plek 'a'. Want dat is zonde van het geheugen en je gebruikt juist de BitSet om minder geheugen te gebruiken.
De boolean array oplossing laat dat duidelijk zien, want dan staat de grote van de array vast op 26 elementen en kan je niet willekeurig in de set addreseren.

"Beauty is the ultimate defence against complexity." David Gelernter

Pagina: 1