Avatar billede mikkel_sommer Nybegynder
09. juni 2005 - 21:55 Der er 12 kommentarer og
2 løsninger

Problemer med en metode til bogstav kombinationer

Jeg vil lave en metode som udskriver de forskellige mulige bogstav kombinationer med eksempelvis a, b, c, d.
Indtil videre har jeg lavet forsøget i en main.
Koden er som følger:

import java.util.*;

public class Ord
{
  public static void main(String[] args)
  {
    String s1 = "";
    String s2 = "";
    String s3 = "";
    String s4 = "";
    Vector start = new Vector();
    start.addElement((String)"a");
    start.addElement((String)"b");
    start.addElement((String)"c");
    start.addElement((String)"d");
    Vector v1 = new Vector();
    Vector v2 = new Vector();
    Vector v3 = new Vector();

    for(int a = 0; a < 4; a++)
    {
      //System.out.println("løkke 1 kører "+a);
      v1 = start;
      s1 = "";
      s1 = (String)v1.get(a);
      v1.removeElementAt(a);
      for(int b = 0; b < 3; b++)
      {
        //System.out.println("løkke 2 kører "+b);
        v2 = v1;
        s2 = s1 + (String)v2.get(b);
        v2.removeElementAt(b);
        for(int c = 0; c < 2; c++)
        {
          //System.out.println("løkke 3 kører "+c);
          v3 = v2;
          //System.out.println("v2 er "+v2.size());
          //System.out.println("v3 er "+v3.size());
          s3 = s2 + (String)v3.get(c);
          v3.removeElementAt(c);
          s4 = s3 + v3.get(0);
          System.out.println(s4);
        }
      }
    }
  }
}

Problemet er at i den sidste forløkke lykkedes det på, for mig ubegribelig vis, også at reducere indholdet af v2.
Som jeg ser det bør indholdet af v2 i den sidste forløkke hele tiden være 2 da det kun er i v3 jeg remover et element og når så løkken igen kører sætter v3 = v2. Med her er indholdet af v2 også blevet reduceret og jeg ender ud med en ArrayIndexOutOfBoundsException.

Kommentarerne er bare for at følge med i løkkernes gennemløb og vectorenes størrelser.

Håber der er nogen der har et forslag til hvad der kan være galt eller måske en meget nemmere måde at løse problemet på...
Avatar billede arne_v Ekspert
09. juni 2005 - 22:00 #1
det plejer bedst at gøres via rekursion
Avatar billede arne_v Ekspert
09. juni 2005 - 22:02 #2
eksempel:

package june;

public class Comb {
    public static void process(char[] b) {
      for (int j = 0; j < b.length; j++) {
          System.out.print(" " + b[j]);
      }
      System.out.println();
    }
    public static void allcomb(char[] a, int len, char[] b, int ix, int start) {
      if (ix < b.length) {
          for (int i = start; i < a.length; i++) {
            b[ix] = a[i];
            allcomb(a, len, b, ix + 1, i + 1);
          }
      } else {
          process(b);
      }
    }
    public static void allcomb(char[] a, int len) {
      char[] b = new char[len];
      allcomb(a, len, b, 0, 0);
    }
    public static void allcomb(char[] a) {
      for (int len = 1; len <= a.length; len++) {
          allcomb(a, len);
      }
    }
    public static void main(String[] args) {
      char[] a = { 'a', 'b', 'c', 'd' };
      allcomb(a);
    }
}
Avatar billede mikkel_sommer Nybegynder
09. juni 2005 - 22:10 #3
Har prøvet det og det ser fint ud, men det output jeg havde forestillet mig var:
a b c d
a b d c
a c b d
a c d b
a d b c
a d c b
osv.
Avatar billede arne_v Ekspert
09. juni 2005 - 22:13 #4
ah - permutationer - ikke kombinationer

5 minutter
Avatar billede arne_v Ekspert
09. juni 2005 - 22:18 #5
package june;

public class Perm {
    public static void writePerm(char[] a, String prefix, int ix, boolean[] used) {
        if(ix < a.length) {
            for(int i = 0; i < a.length; i++) {
                if(!used[i]) {
                    used[i] = true;
                    writePerm(a, prefix + a[i], ix + 1, used);
                    used[i] = false;
                }
            }
        }
        else
        {
            System.out.println(prefix);
        }
    }
    public static void writePerm(char[] a) {
        boolean[] used = new boolean[a.length];
        writePerm(a, "", 0, used);
    }
    public static void main(String[] args) {
        char[] a = { 'a', 'b', 'c', 'd' };
        writePerm(a);
    }
}
Avatar billede jakoba Nybegynder
10. juni 2005 - 00:48 #6
det var dog en hulens masse parametre :-))

class Perm {

  private void skrivPerm( String[] ar, int level ) {
    int maxLgt = ar.length();
    if ( level == maxLgt-1 ) {
      for (int i=0; i<maxLgt; i++ ) System.out.print( ar[i] );
      System.out.println();
    } else {
      String temp = ar[level];
      for (int i = level; i<maxLgt; i++ ) {
        ar[level] = ar[i];
        ar[i] = temp;
        skrivPerm( ar, level + 1 );
        ar[i] = ar[level];
      }
      ar[level] = temp;
    }
  } // endmethod

  public static void main(String[] args) {
    String[] ar = { "a", "b", "c", "d" };
    writePerm( ar, 0 );
  } // endmethod

} // endclass
Avatar billede snoop_one Nybegynder
10. juni 2005 - 00:53 #7
Arne_v's løsning er klart nemmere (hvis man kan gennemskue rekursion).
Der hvor du har dit problem, er at JAVA behandler alle variabler som referencer.
Dvs. i dit program har du faktisk kun en vektor du køre det hele på, nemlig v1.
Fordi når du skriver v2 = v1 betyder det ikke at indholdet af v1 bliver flyttet over i v2! men, at v2 nu pejer på samme data som v1. osv. mht. v3.
For at løse problemet skal du erstatte v2 = v1 med v2 = new Vector(v1) dermed laver du et nyt object som v2 pejer på med værdierne fra v1.

Håber ikke at det hele er sort snak :)
Avatar billede mikkel_sommer Nybegynder
10. juni 2005 - 02:09 #8
Nej det er helt fint snoop.
Hvis du og arne smidder et svar er det bare helt i top.
Avatar billede arne_v Ekspert
10. juni 2005 - 07:40 #9
svar
Avatar billede soreno Praktikant
10. juni 2005 - 08:31 #10
Jeg har også en på lager jeg gerne vil bidrage med:

public class Permutation {

  public static void perm(char array[], int index) {   
    if (index == array.length - 1) {
      System.out.println(array);
    } else {
      for (int i = index; i < array.length; i++) {
        char temp = array[index];
        array[index] = array[i];
        array[i] = temp;       
        perm((char[]) array.clone(), index + 1);
      }
    }
  }

  public static void main(String[] args) {
    char test[] = "abc".toCharArray();
    perm(test, 0);
  }
}
Avatar billede snoop_one Nybegynder
11. juni 2005 - 10:15 #11
svar
Avatar billede touel Nybegynder
12. juni 2005 - 21:44 #12
soreno - jeg vil gerne lige vide en ting. Hvis man gransker din kode så kan man se at man i starten har med værdierne a og a at gøre godt med. Bagefter er det b og b. Men hvordan hopper den så pludselig over til c og b ????
Avatar billede soreno Praktikant
14. juni 2005 - 08:23 #13
touel:

Jeg forstår ikke dit spørgsmål, men gætter på det er swap funktionen der er svaret.. :-)
Dette kode er jo bare swap af 2 elementer i arrayet:
        char temp = array[index];
        array[index] = array[i];
        array[i] = temp;
Avatar billede soreno Praktikant
14. juni 2005 - 08:24 #14
I øvrigt, burde jeg ikke få en mail når der er nye indlæg i spørgsmålet ?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester