Hallo,
ich habe habe ein Array mit 192 Einträgen. Dabei handelt es sich um die
Daten für eine LED-Matrix. Wie kann ich jetzt die 0x00 auf einmal
kürzen, wenn es 2 und mehr mal hintereinander kommt:
BSP:
data[0] = 0x30
data[1] = 0x00
data[2] = 0x00
data[3] = 0x00
data[4] = 0x45
data[5] = 0x82
data[6] = 0x00
zu
data[0] = 0x30
data[1] = 0x00
data[2] = 0x45
data[3] = 0x82
data[4] = 0x00
data[5] = 0x00
data[6] = 0x00
Bisher habe ich schon ein wenig rumexperimentiert. Bin aber zu noch
nichts gekommen. Ich habe nur bisher das Datenarray in ein 2. Array
gespeichert. Am Ende wird das 2. Array wieder in das erste geschrieben.
Dazwischen sollte dann aus dem 2. Array die aufeinanderfolgenden 0x00
gekürzt werden.
Hat jemand eine Ahnung wie das geht? Muss kein Code sein, eine Idee
reicht auch schon.
Tim
Ich ersehe zwar keine Sprache, in der du das ganze machen willst, aber
vom Prinzip her könntest du dir das 2. Array fast sparen und statt
dessen eine Liste von Pointern anlegen. Du schreibst halt nur die
Pointer auf Daten in die Liste, welche auf Daten ungleich 0 zeigen.
Also Array durchlaufen und immer wenn der Wert der Stelle auf die dein
Laufpointer grad zeigt ungleich 0 ist, Laufpointer in eine neue Liste
kopieren....
Danach sollte eine Liste entsanden sein, die quasie ein neues Array nur
aus Werten ist...
Ist das Array fest vorgegeben und wird erst von Dir bearbeitet, oder
erzeugst Du es selbst? Im letzteren Fall könnte man einfach eine
Hilfsvariable einführen und prüfen, ob der letzte in das Array
geschriebene Wert bereits Null war, und anstatt schon wieder eine Null
zu schreiben überspringt man dies einfach.
Für den Obfuscated C Contest reicht's noch nicht, aber ich habe mir Mühe
gegeben ;-)
1
voids(uint8_td[],uint8_tn,uint8_tz){
2
uint8_ti,j=0,c=0;
3
for(i=0;i<n;i++)
4
if((c=d[i]?0:c+1)<=z)
5
d[j++]=d[i];
6
while(j<n)
7
d[j++]=0;
8
}
d ist das Array mit den Daten, n die Anzahl der Elemente im Array und z
die maximale Anzahl der Nullen, die in Serie stehen bleiben dürfen (in
deinem Fall ist z=1). Nach der Ausführung stehen die zusammengeschobenen
Daten im gleichen Array.
Nachtrag zu meiner Version:
Die erste Schleife ("letztes Element !=0 suchen") ist sinnlos
und kann weg.
Gedacht war sie mal, um nicht immer die schon am Ende angesammelten
Nullen nach vorne schieben zu müssen; das erfüllt sie aber eh nicht.
Korekt geschrieben wäre es effizienter, macht aber sonst keinen
Unterschied.
Ich schaue es mir morgen nochmal an.
Hallo,
vielen Dank für eure Lösungen! Ich hab mich von der von Klaus Wachtler
inspirieren lassen und meine Geschrieben.
Es war übrigens 0xFF statt 0x00 :)
Meine Lösung (falls jemand sich dafür interessiert)
Tim H. schrieb:
> Hallo,>> vielen Dank für eure Lösungen! Ich hab mich von der von Klaus Wachtler> inspirieren lassen und meine Geschrieben.> Es war übrigens 0xFF statt 0x00 :)>> Meine Lösung (falls jemand sich dafür interessiert)
Zur Übung für dich: Und jetzt das Ganze ohne Zwischenarray.
(Ist nicht wirklich schwer)
Warum diese Übung?
Ganz einfach: Was machst du wenn dein Array im µC den halben Speicher
belegt und du den Speicher ganz einfach nicht hast um dir temporär eine
Kopie erlauben zu dürfen.
(Von Laufzeitüberlegungen einmal ganz abgesehen. Array umkopieren kostet
auch Zeit. Wobei in diesem Fall diese Zeit noch nicht einmal gut
investiert ist. Das Umkopieren bringt nämlich überhaupt nichts. Keine
Arbeitserleichterung, keinen Speed. Gar nichts. Es belegt nur Speicher
:-)
Danke nochmal. Bei deiner Lösung hat er den Abstand zwischen den Zeichen
auf 0 verkleinert... 1 sollte ja sein. Ich hab einfach nochmal i_over
weiterzählen lassen :). Aber Danke!
Im Anhang mal was das optimieren gebracht hat.
1
//optimize1
2
uint8_ti_over=0;
3
4
for(i=0;i<191;i++)
5
{
6
if(data[i]==0xFF){// einmal 0xFF ist ok. Aber alle die jetzt
Karl heinz Buchegger schrieb:
> @yalu> schöne Lösung :-)
Naja, die mit Klaus' und deiner Hilfe entstandene letzte Variante von
Tim unterscheidet sich ja gar nicht mehr so arg von meiner, bis auf die
innere Schleife, die mit Hilfe dieser Abfrage
1
if((c=(d[i]==p)?0:c+1)<=z)
als Bestandteil der äußeren läuft. Aber gerade diese Abfrage ist es, die
wohl bei den meisten (zurecht) ein kaltes Grausen auslöst ;-)
ich erwähne jetzt vielleicht besser nicht, was eine
unkommentierte Funktion s mit so poetischen Variablennamen
wie d, i, p, c und z bei mir auslöst...
Nein, ich tue es nicht.
:-)
Wenn Du der Reihe nach in das Array schreibst:
Erhöhe den Pointer oder Index erst, wenn der aktuelle Inhalt oder der
neue Wert ungleich 0 ist.
1
if(data[i]||neuerWert)
2
data[++i]=neuerWert;
Wenn über den Index nicht der Reihe nach auf das Array zugegriffen wird,
dann hat die Position wohl irgendeine Bedeutung:
Beim Verschieben solltest Du festhalten, wo ein neuer Wert denn jetzt
hinzukommen hat. Im Prinzip kannst Du das Array dann komprimieren, aber
nicht einfach angeblich leere Einträge löschen.
Klaus Wachtler schrieb:
> ich erwähne jetzt vielleicht besser nicht, was eine> unkommentierte Funktion s mit so poetischen Variablennamen> wie d, i, p, c und z bei mir auslöst...> Nein, ich tue es nicht.> :-)
Der Fairness halber hat Yalu ja auch den OCCC erwähnt.
Für diesen Bewerb ist dieser Code allerdings noch lange nicht kryptisch
genug :-)