Auflistung aller Groß-Kleinschreibungsmöglichkeiten eines Strings



  • ähm, Großziffer!?
    Was meinst du mit Großziffer von 7?


  • Mod

    Tw1x schrieb:

    ähm, Großziffer!?
    Was meinst du mit Großziffer von 7?

    Wie sieht eine groß geschriebene '7' aus?



  • haha, lol xD

    Nein, also wie oben erwähnt, die Zahlen werden ja ignoriert... hoffe ich zumindest.



  • Bei der Umwandlung schon.
    Aber nicht bei der Ausgabe.

    Und schau dir mal die Möglichkeiten der Formatspecifier von printf an. Das f bedeutet da übringes formatiert. Ok probier mal

    printf("%3d. Möglichkeit: %s\n", i+1, temp);
    


  • Ok, also das %3d bringt ja nur die Einrückung (wie gesagt, die Ausgabe ist ja eigentlich egal...), was ich aber nicht verstehe ist, warum die Buchstabenkombinationen doppelt und dreifach vorkommen, es soll ja jede Kombination 1 einziges Mal vorkommen, also so nach dem Motto:

    v76tcthg4j
    v76tcthg4J
    v76tcthG4j
    v76tcthG4J
    //und so weiter...
    

    Es listet aber bereits mit der 2. Möglichkeit ein großes "V" auf, es sollte lauf 0000001 aber klein sein...

    Sonst noch Vorschläge vielleicht?



  • Hab ich irgendwannmal geschrieben. Ist zwar WIN, aber du wirst das Prinzip verstehen.

    private:
    	std::wstring m_input;
    	size_t m_len; // length of m_input
    	std::vector<std::wstring> m_vResults; // results
    

    Aufruf:

    RecGenerate( m_input, 0 );
    
    void CGenerator::RecGenerate( std::wstring output, size_t pos )
    {
    	TCHAR ch = output.at( pos );
    	if( _istalpha( static_cast<wint_t> (ch) ) )
    		ch = flip( ch );
    	else ch = _T('\0');
    
    	if( pos < m_len )
    	{
    		RecGenerate( output, pos + 1 );
    		if( ch )
    		{
    			output.replace( pos, 1, 1, ch );
    			RecGenerate( output, pos + 1 );
    		}
    	}
    	else
    	{
    		//wcout << output << endl;
    		m_vResults.push_back( output );
    		if( ch )
    		{
    			output.replace( pos, 1, 1, ch );
    			//wcout << output << endl;
    			m_vResults.push_back( output );
    		}
    	}
    } // void CGenerator::RecGenerate( std::wstring output, size_t pos )
    
    TCHAR flip( TCHAR ch )
    {
    	wint_t wc = static_cast<wint_t> (ch);
    	if( _istalpha( wc ) )
    	{
    		if( _istupper( wc ) )
    			ch = _totlower( ch );
    		else
    			ch = _totupper( ch );
    	}
    	return( ch );
    }
    


  • Hallo,

    danke für eure Antworten, die letzte Antwort verstehe ich gar nicht, das heißt, ich verstehe noch "void" und andere Schlüsselwörter, aber da ich ein ziemlicher Anfänger bin, verstehe ich von dem Code gar nichts...

    Ich habe mir mein Programm nochmal angeschaut und jetzt die Reihenfolge umdrehen wollen, mit der das aufgelistet wird (nicht mehr vorne groß-klein-groß-klein-... sondern hinten an den Strings); habe das auch jetzt geschafft, durch die Einführung einer weiteren Zählvariable k, die ich statt dem log2-Zeugs da verwende.
    Dann ist mir noch aufgefallen, dass ich die 128 in der inneren for-Schleife falsch gewählt habe, da muss ne 64 hin. Somit hab ich die Lösung fast, jetzt nur noch schnell die Zahlen ignorieren lassen und nochmal testen, dann funktionierts.
    Ich werde die lauffähige Lösung hier noch reineditieren, danach kann geclosed werden.



  • Tw1x schrieb:

    die letzte Antwort verstehe ich gar nicht, das heißt, ich verstehe noch "void" und andere Schlüsselwörter, aber da ich ein ziemlicher Anfänger bin, verstehe ich von dem Code gar nichts...

    Ja, eigentlich wundere ich mich selber was ich da zusammengebastelt habe. Aber es fumktioniert. Auch mit Zahlen, Sonderzeichen.



  • Jetzt, da du deine Aufgabe selber gelöst hast, kann ich ja meinen Ansatz zeigen.

    int main(void) {
      int i, j, k;
      char test[] = "v76tcthg4j";
      const int test_size = strlen(test);
      for(i = 0; i < (1<<(test_size - 3)); i++) {
        printf("%3d. Möglichkeit: ", i+1);
        for (j=k=0; j<test_size; j++, k++) {
          while (isdigit(test[j]))
            putchar(test[j++]);
          putchar((i & (1<<k)) ? toupper(test[j]) : test[j]);
        }
        putchar('\n');
      }
    }
    

    @EOP: Das ist der Beweis, dass man mit ein bisschen C-Kenntnis viel weiter kommt als mit ein bisschen C++-Kenntnis. Dein Code ist langsam (O(2^(alphas+nonalphas)) statt O((2^alphas)+nonalphas), Rekursion, Zwischenspeichern in vector) und umständlich (win-zeugs, m_len redundand, Rekursion, warum replace, Pseudo-OOP).



  • Was ist denn an m_len redundant? Ich brauch ja ne Abbruchbedingung für die Rekursion. So berechne ich sie einmal und "gut is".



  • Du hast doch schon m_input.length() ?



  • Ok, das "reineditieren" von meinem letzten Post einfach wegdenken, habe es nicht geschafft, die Zahlen mit rein zu kriegen...

    Mein Dank geht an hsrtrzh<W4, dankesehr, dein Code funktioniert perfekt... nahezu perfekt zumindest, werde die Reihenfolge noch umdrehen, will nämlich, dass am Stringende zuletzt das Zeichen variiert wird, also so:

    ...
    V76TCTHg4j
    V76TCTHg4J
    V76TCTHG4j
    V76TCTHG4J
    

    Wie ich sehe, arbeitest du mit Bitverschiebung? (Bitverschiebungen mag ich gar nicht, die verstehe ich zwar grad so, aber ich finde die so unübersichtlich...)
    Könntest du den Code noch ausführlich kommentieren, dass ich ihn verstehe? Funktionieren tut er ja...

    Danke für die Lösung des Problems!



  • @ hsrtrzh<W4

    Versuch mal dein Programm mit

    char test[] = "g4j";
    

    oder

    char test[] = "g4jx";
    

    und dann test mal meins.

    Fällt dir was auf?



  • Ich verstehe nicht ganz, bist du sicher dass du den

    char test[]
    

    und nicht den

    char temp[]
    

    meintest?

    Ich stelle nur fest, dass es mit dem x ca. 10 mal jede Möglichkeit auflistet, also z.B.
    128.
    128.
    128.
    ...

    aber ich verstehe nicht ganz, was du meinst... oder meinst du die Unabhängigkeit des Input-Strings bei deinem Code? Das weiß ich schon, das ist nur für genau den String der Code von mir^^



  • So, hab die Lösung von hsrtrzh<W4 umgeschrieben, dass er mir den Output in ne *.txt schreibt, und bin vorerst befriedigt mit dem Ergebnis.

    Danke für die schnelle Hilfe; hach, ich liebe Foren! xD

    Beste Grüße & gn8
    Tw1x



  • original:

    char test[] = "v76tcthg4j";
    

    und mit

    char test[] = "g4j";
    

    Ausgabe:
    1. Möglichkeit "g4j"
    und das war's dann schon auch.



  • Ihr macht's euch aber kompliziert.

    #include <ctype.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void print_permutations_aux(char *s, size_t pos) {
      if(s[pos] == '\0') {
        puts(s);
      } else if(isalpha(s[pos])) {
        s[pos] = toupper(s[pos]);
        print_permutations_aux(s, pos + 1);
        s[pos] = tolower(s[pos]);
        print_permutations_aux(s, pos + 1);
      } else {
        print_permutations_aux(s, pos + 1);
      }
    }
    
    void print_permutations_inplace(char *s) {
      print_permutations_aux(s, 0);
    }
    
    void print_permutations(char const *s) {
      char *p = malloc(strlen(s) + 1);
      strcpy(p, s);
      print_permutations_inplace(p);
      free(p);
    }
    
    int main() {
      print_permutations("g4jx");
    
      return 0;
    }
    


  • Dumme Frage:
    Wofür ist print_permutations_inplace nötig? (Bin nicht mehr ganz nüchtern).

    E#1:
    Ah, wohl für free.

    E#2:
    Nö wohl doch nicht.



  • wie jetzt? es gibt also vorgefertigte funktionen für eine permutation? verstehe ich das jetz richtig? wie gerne ich den code testen würde... bin leider nimmer am pc und kann mir erst in 45 min nen c-compiler fürs handy holen... mal sehen, danke schonmal jetzt^^



  • EOP schrieb:

    Dumme Frage:
    Wofür ist print_permutations_inplace nötig? (Bin nicht mehr ganz nüchtern).

    Ist streng genommen nicht nötig, aber wenn du schon einen schreibbaren Buffer hast, der geclobbert werden kann, macht es wenig Sinn, eine Kopie davon anzulegen. In dem Fall kann _inplace benutzt werden.

    @tw1x: Das sind keine vorgefertigten Funktionen. Der komplette Code ist in dem Schnipsel enthalten.


Anmelden zum Antworten