Einen "Pfeil" beliebiger Größe ausgeben
-
Ich habe erstmal ein Kreuz erzeugt .... dann den stengel ... und jetzt überlege ich wie ich oben die Spitze komplett bekomme. Ich werd noch wahnsinnig
-
johnas schrieb:
Ich habe erstmal ein Kreuz erzeugt .... dann den stengel ... und jetzt überlege ich wie ich oben die Spitze komplett bekomme. Ich werd noch wahnsinnig
Nimmsu lieber zwei char arrays a, b der Größe N+1, das ist die ungerade Anzahl der Zeichen in der Zeile plus Terminator. (N ist die Anzahl der Spalten.)
Initialisieren: a schreibst du N mal mit '0' voll, b bekommt vorn ne '1' (Terminierung nicht vergessen).
Beginne mit Index i = N/2, das ist die Anfangsposition, an der du mit snprintf b in a einfügst.solange wie strlen(b) < strlen (a): einfügen von b in a an pos a+i, ausgabe a mit zeilenumbruch, (bzw. Initialisierung einer Matrix) i wird um eins vermindert, b wächst um "11"
Das wäre z.B. auch der Code für die zeilenweise Initialisierung einer char[M][N] Matrix.
M: Zeilen, N: Spalten.
M = N/2 + 1, N ungerade, N/2 Ganzzahldivision.
-
Big Brother schrieb:
Nimmsu lieber zwei char arrays a, b der Größe N+1, das ist die ungerade Anzahl...
wozu arrays? das kann er doch alles mit putchar() direkt ausgeben.
-
;fricky schrieb:
Big Brother schrieb:
Nimmsu lieber zwei char arrays a, b der Größe N+1, das ist die ungerade Anzahl...
wozu arrays? das kann er doch alles mit putchar() direkt ausgeben.
Ich wollte natürlich cool sein und nur eine Schlefie benutzen.
Man kann damit auch Matrizen schneller initialisieren, wenn man memcpy, memset etc. nimmt, als mit putchar.
-
Big Brother schrieb:
Ich wollte natürlich cool sein und nur eine Schlefie benutzen.
nur eine schleife für das ganze pfeil-bildchen? sehr abgefahren. die steigerung wäre dann wohl ganz ohne schleife, aber immer noch mit variabler pfeilgrösse *fg*
-
;fricky schrieb:
Big Brother schrieb:
Ich wollte natürlich cool sein und nur eine Schlefie benutzen.
nur eine schleife für das ganze pfeil-bildchen? sehr abgefahren. die steigerung wäre dann wohl ganz ohne schleife, aber immer noch mit variabler pfeilgrösse *fg*
Ohne Schleife gehts auch variabel, das wäre doch der Jobgenerator.
Zu jedem Pfeilprogramm wird ein Coder mit ausgeliefert, der vor der Benutzung des Programms schnell mal eben vor Ort das Array im Quellcode an die Parameter anpasst und neu kompiliert.
-
Big Brother schrieb:
Ohne Schleife gehts auch variabel, das wäre doch der Jobgenerator.
nee, das wäre dann eine rekursive lösung. sowas haben wir ja schonmal gesehen hier (mit dieser teuflischen raute, mit der anfänger auch gern gequält werden). *fg*
-
Hi danke für die Antwort..
Ich habe es mir jetzt ein paar mal durchgelesen und versucht es mir auf einem Zettel vorzustellen aber ich verstehe nicht ganz wie du das meinst.
Was du du mit Anfangsposition meinst ist glaube ich klar sogesehen die mitte der Spalten wo die erste 1 hinkommt ( also Spitze des Pfeiles).
Was bewirkt snprintf ? Hab mal gegoogelt aber da waren nur unverständliche englische Beschreibungen ^^.
Warum solange strln(b) < strln(a) ?
Habe bei der Aufgabe echt ein Brett vor dem Kopf -.- .
Johnas
-
Johnas schrieb:
Warum solange strln(b) < strln(a) ?
Das ist ein mögliches Abbruchkriterium für die Schleife, die ja irgenwann mal zu ende sein muss.
Kannst auch while(i>=0) nehmen oder so...snprintf fügt ab einer bestimmten Postition in einer Zeichenkette eine bestimmte Anzahl von Zeichen ein. In diesem Fall ist wohl memcpy die bessere Wahl, weil nichts konvertiert wird.
// N=5 int i = 5/2, n = 1; char a[5+1] = "00000"; char b[5+1] = "11111"; // snprintf ( a+i , n, "%s", b ); memcpy(a+i, b, n); puts(a);
Das ist schon fast alles. Brauchst noch ne Schleife, in der i um 1 vermindert und n 2 erhöht wird.
-
^^das sieht ja immer haarsträubender aus *fg*
warum nicht einfach zeichenweise ausgeben?
-
Warum doch? An den Gründen hat sich nichts geändert. :p
Bei ASCII Grafik Animationen z.B. bist du mit nem Array am besten beraten.
Für einfach so mal ausgeben reicht es natürlich auch zeichenweise
Ich finde das gar nicht so haarsträubend:#define N 43 int pfui() { puts("Pfui!"); return 1; } int main() { char a[N+1]={0}, b[N]={0}; int i=N/2, n=1, arr[] = {1,2}; if (!(N%2)) return pfui(); // Pfeil Formfaktor Defender :) memset( b, '1', N ); memset( a, '0', N ); while (i>=0) memcpy(&a[i--],b,n), puts(a), n+=2; return 0; }
-
Big Brother schrieb:
Ich finde das gar nicht so haarsträubend:
isses aber, diese memsets/memcpys, zwei arrays usw. brauchste doch garnicht. und bei geraden N kommt deine methode auch ins straucheln. wenn du alles in einem array haben willst, dann mach doch etwa sowas:
void arrowhead (char *a, int size) { int s, t; size = (size-1)/2; for (s=0; s<=size; s++) { for (t=0; t<size-s; t++) *a++ = '0'; for (t=0; t<s*2+1; t++) *a++ = '1'; for (t=0; t<size-s; t++) *a++ = '0'; *a++ = '\n'; } }
aufruf ungefähr so:
... #define N 13 // zeilenlaenge #define ARRAYSIZE(a) (((a)*(a)+2*(a)+3)/2) // speicherbedarf ... char a[ARRAYSIZE(N)] = {0}; // array für die ganze spitze arrowhead (a, N); // spitze machen puts (a) // ... und anzeigen ...
-
;fricky schrieb:
isses aber, diese memsets/memcpys, zwei arrays usw. brauchste doch garnicht.
Stimmt, ein Array und ein memset statt memcpy tuts auch.
Du bist ein *X++ Fan, ne?;fricky schrieb:
und bei geraden N kommt deine methode auch ins straucheln.
Die tut wenigstens nicht so, als könnte sie es in einer 'geraden Zeilenumgebung' darstellen, sondern macht Schimpfepfui :p
Ok, ist aber ne gute Idee, die Anzahl automatisch ungerade zu machenwenn du alles in einem array haben willst, dann mach doch etwa sowas:
//...
Jepp, oder sowas:
#include <stdio.h> #include <memory.h> #define N 80 // Zeilenlänge :), Anzahl der sichtbaren Zeichen für die Grundseite. #define ODD ((N-1)/2*2+1) // Macht die Zeilenlänge ungerade. #define LSZ (ODD+1) // Linesize, Speicherbedarf für eine Zeile. #define H (ODD/2+1) // Höhe des Dreiecks in Zeilen. #define SZ (LSZ*H+1) // Speicherbedarf fürs Array. (+1: Terminierung) char Dreieck[SZ]; // Automatische 0 Terminierung. void dreieck() { int i, n = 1, pos = ODD/2; memset ( Dreieck, '0', sizeof(Dreieck)-1 ); // -1: Terminator nicht überschreiben. for ( i = 0; i<H; i++, n += 2, pos-- ) { Dreieck[LSZ*(i+1)-1] = '\n'; memset ( &Dreieck[i*LSZ+pos], '1', n ); } } int main() { dreieck(); puts(Dreieck); return 0; }
Hab mal irgendwo gelesen, das hinter memset und co. speziell für die jeweilige Rechnerarchitektur optimierte Maschinenbefehle stecken (was man von *X++ vermutlich nicht behaupten kann :p ).
-
Big Brother schrieb:
Jepp, oder sowas:
schon viel besser.
Big Brother schrieb:
Hab mal irgendwo gelesen, das hinter memset und co. speziell für die jeweilige Rechnerarchitektur optimierte Maschinenbefehle stecken
klar, wenn's maschinenbefehle gibt, die ganze blöcke füllen können, dann werden die genommen. anonsten ist es ziemlich optimierter assembler-code.
Big Brother schrieb:
(was man von *X++ vermutlich nicht behaupten kann.
doch auch, für einfache schleifen erzeugen viele compiler sehr schnellen code. die haben sowas wie 'ne mustererkennung drin. um dem compiler zu helfen, sollte deshalb code so simpel wie möglich sein.