Forum: Compiler & IDEs Leere Einträge aus Array löschen


von Tim H. (hotty) Benutzerseite


Lesenswert?

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

von Bastler (Gast)


Lesenswert?

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...

von Bastler (Gast)


Lesenswert?

Nachtrag: Vergiss die Frage mit der Sprache, hab grad gesehen, dass das 
im GCC Forum steht... bin sonst mehr bei den µC und deshalb meien 
Frage...

von Mark B. (markbrandis)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

Vielleicht in der Art (nicht getestet, bitte noch mit
verschiedenen Fällen prüfen!!!):
1
#include <stdio.h>
2
#include <stdint.h>
3
#include <stdlib.h>
4
5
6
void moveBackDuplicateZero_ui8( uint8_t arr[], unsigned int nArr )
7
{
8
  unsigned int iArr;
9
10
  // letztes Element !=0 suchen:
11
  for( iArr=nArr; iArr>=0; --iArr )
12
  {
13
    if( arr[iArr] )
14
    {
15
      break;
16
    }
17
  }
18
19
  for( iArr=1; iArr<nArr; ++iArr )
20
  {
21
    if( arr[iArr]==0 && arr[iArr-1]==0 )
22
    {
23
      // Beginn einer 0-Folge gefunden!
24
      // Ab hier alle Nullen nach hinten schieben, alle anderen
25
      // Elemente vorziehen.
26
      // Ende der 0-Folge suchen:
27
      unsigned int nLast0 = iArr;
28
      while( nLast0<nArr && arr[nLast0]==0 )
29
      {
30
        nLast0++;
31
      }
32
      // nLast0 ist jetzt der Index NACH dem letzten 0-Element.
33
      // Um (nLast0-iArr) Positionen müssen jetzt alle restlichen
34
      // Elemente nach vorne gezogen werden, bzw. die letzten zu 0
35
      // gesetzt werden:
36
      {
37
        unsigned int iArrMove;
38
        for( iArrMove=iArr; iArrMove<nArr; ++iArrMove )
39
        {
40
          if( iArrMove<(nArr-(nLast0-iArr)) )
41
          {
42
            arr[iArrMove] = arr[iArrMove+nLast0-iArr];
43
          }
44
          else
45
          {
46
            arr[iArrMove] = 0;
47
          }
48
        }
49
      }
50
    }
51
  }
52
}
53
54
int main( )
55
{
56
  uint8_t    arr_test[192];
57
  uint8_t    arr[192] =
58
    {
59
      0x30,
60
      0x00,
61
      0x00,
62
      0x00,
63
      0x45,
64
      0x82,
65
      0x00,
66
      0x30,
67
      0x00,
68
      0x00,
69
      0x00,
70
      0x45,
71
      0x82,
72
      0x00,
73
      0x30,
74
      0x00,
75
      0x00,
76
      0x00,
77
      0x45,
78
      0x82,
79
      0x00,
80
      0x30,
81
      0x00,
82
      0x00,
83
      0x00,
84
      0x45,
85
      0x82,
86
      0x00,
87
      0x30,
88
      0x00,
89
      0x00,
90
      0x00,
91
      0x45,
92
      0x82,
93
      0x00,
94
      0x30,
95
      0x00,
96
      0x00,
97
      0x00,
98
      0x45,
99
      0x82,
100
      0x00,
101
      0x30,
102
      0x00,
103
      0x00,
104
      0x00,
105
      0x45,
106
      0x82,
107
      0x00,
108
      0x30,
109
      0x00,
110
      0x00,
111
      0x00,
112
      0x45,
113
      0x82,
114
      0x00,
115
      0x30,
116
      0x00,
117
      0x00,
118
      0x00,
119
      0x45,
120
      0x82,
121
      0x00,
122
      0x30,
123
      0x00,
124
      0x00,
125
      0x00,
126
      0x45,
127
      0x82,
128
      0x00,
129
      0x30,
130
      0x00,
131
      0x00,
132
      0x00,
133
      0x45,
134
      0x82,
135
      0x00,
136
      0x30,
137
      0x00,
138
      0x00,
139
      0x00,
140
      0x45,
141
      0x82,
142
      0x00,
143
      0x30,
144
      0x00,
145
      0x00,
146
      0x00,
147
      0x45,
148
      0x82,
149
      0x00,
150
      0x30,
151
      0x00,
152
      0x00,
153
      0x00,
154
      0x45,
155
      0x82,
156
      0x00,
157
      0x30,
158
      0x00,
159
      0x00,
160
      0x00,
161
      0x45,
162
      0x82,
163
      0x00,
164
      0x30,
165
      0x00,
166
      0x00,
167
      0x00,
168
      0x45,
169
      0x82,
170
      0x00,
171
      0x30,
172
      0x00,
173
      0x00,
174
      0x00,
175
      0x45,
176
      0x82,
177
      0x00,
178
      0x30,
179
      0x00,
180
      0x00,
181
      0x00,
182
      0x45,
183
      0x82,
184
      0x00,
185
      0x30,
186
      0x00,
187
      0x00,
188
      0x00,
189
      0x45,
190
      0x82,
191
      0x00,
192
      0x30,
193
      0x00,
194
      0x00,
195
      0x00,
196
      0x45,
197
      0x82,
198
      0x00,
199
      0x30,
200
      0x00,
201
      0x00,
202
      0x00,
203
      0x45,
204
      0x82,
205
      0x00,
206
      0x30,
207
      0x00,
208
      0x00,
209
      0x00,
210
      0x45,
211
      0x82,
212
      0x00,
213
      0x30,
214
      0x00,
215
      0x00,
216
      0x00,
217
      0x45,
218
      0x82,
219
      0x00,
220
      0x30,
221
      0x00,
222
      0x00,
223
      0x00,
224
      0x45,
225
      0x82,
226
      0x00,
227
      0x30,
228
      0x00,
229
      0x00,
230
      0x00,
231
      0x45,
232
      0x82,
233
      0x00,
234
      0x30,
235
      0x00,
236
      0x00,
237
      0x00,
238
      0x45,
239
      0x82,
240
      0x00,
241
      0x30,
242
      0x00,
243
      0x00,
244
      0x00,
245
      0x45,
246
      0x82,
247
      0x00,
248
      0x30,
249
      0x00,
250
    };
251
252
253
  unsigned int iAusgabe;
254
255
  unsigned int i;
256
257
  for( i=0; i<sizeof(arr)/sizeof(arr[0]); ++i )
258
  {
259
    arr_test[i] = arr[i];
260
  }
261
262
  moveBackDuplicateZero_ui8( arr, sizeof(arr)/sizeof(arr[0]) );
263
264
  for( iAusgabe=0; iAusgabe<sizeof(arr)/sizeof(arr[0]); ++iAusgabe )
265
  {
266
    printf( "{%3u]: alt=0x%02x neu==0x%02x\n", iAusgabe, arr_test[iAusgabe], arr[iAusgabe] );
267
  }
268
269
  return 0;
270
}

von Yalu X. (yalu) (Moderator)


Lesenswert?

Für den Obfuscated C Contest reicht's noch nicht, aber ich habe mir Mühe
gegeben ;-)
1
void s(uint8_t d[], uint8_t n, uint8_t z) {
2
  uint8_t i, 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.

von Klaus W. (mfgkw)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

@Yalu: Hoffentlich machen unsere Versionen etwa das Gleiche...

von Tim H. (hotty) Benutzerseite


Lesenswert?

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)
1
  //Code auslesen
2
        for(i = 0; i <= 50; i++){
3
    zeichen = text[i];
4
    db_pointer = zeichen * 6 -1;
5
    for(zei = db_pointer; zei < db_pointer + 6; zei++)
6
    {
7
      data[ofs] = 255 - pgm_read_byte(&charsetDE[zei]);
8
      ofs++;
9
    }
10
  }
11
12
13
  for(i = 0; i < 192; i++)
14
  {
15
      temp[i] = 0xFF;
16
  }
17
18
  //optimize1
19
  uint8_t i_over = 0;
20
21
  for(i = 0; i < 191; i++)
22
  {  
23
    if(data[i] == 0xFF && data[i+1] == 0xFF){
24
      //2 Leere Spalten
25
    }
26
    else{
27
      i_over++;
28
        temp[i_over] = data[i];    
29
    }
30
   }
31
 
32
33
  for(i = 0; i < 192; i++)
34
  {
35
      data[i] = temp[i];
36
  }

von Karl H. (kbuchegg)


Lesenswert?

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 
:-)

von Tim H. (hotty) Benutzerseite


Lesenswert?

Stimmt! Da hast du recht.
1
  uint8_t i_over = 0;
2
3
  for(i = 0; i < 191; i++)
4
  {  
5
    if(data[i] == 0xFF && data[i+1] == 0xFF){
6
      //2 Leere Spalte
7
    }
8
    else{
9
      data[i_over] = data[i];  
10
      i_over++;  
11
    }
12
   }
13
14
  for(i = i_over; i < 191; i++)
15
  {
16
    data[i] = 0xFF; //Rest löschen
17
  }

Gehts noch besser?

von Karl H. (kbuchegg)


Lesenswert?

Tim H. schrieb:
> Stimmt! Da hast du recht.
>
>
1
>   uint8_t i_over = 0;
2
> 
3
>   for(i = 0; i < 191; i++)
4
>   {
5
>     if(data[i] == 0xFF && data[i+1] == 0xFF){
6
>       //2 Leere Spalte
7
>     }
8
>     else{
9
>       data[i_over] = data[i];
10
>       i_over++;
11
>     }
12
>    }
13
> 
14
>   for(i = i_over; i < 191; i++)
15
>   {
16
>     data[i] = 0xFF; //Rest löschen
17
>   }
18
>
>
> Gehts noch besser?

Das würd ich so machen
1
  uint8_t i_over = 0;
2
 
3
  for(i = 0; i < 191; i++)
4
  {
5
    data[i_over++] = data[i];
6
7
    if(data[i] == 0xFF) {  // einmal 0xFF ist ok. Aber alle die jetzt
8
                           // noch hinten drann kommen, fliegen raus
9
      i++;
10
      while( i < 191 && data[i] == 0xFF )
11
        i++;
12
    }
13
  }
14
15
  for(i = i_over; i < 191; i++)
16
    data[i] = 0xFF; //Rest löschen

von Tim H. (hotty) Benutzerseite


Angehängte Dateien:

Lesenswert?

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_t i_over = 0;
3
 
4
  for(i = 0; i < 191; i++)
5
  {
6
    if(data[i] == 0xFF) {  // einmal 0xFF ist ok. Aber alle die jetzt
7
                           // noch hinten drann kommen, fliegen raus
8
      i++;i_over++;
9
      while( i < 191 && data[i] == 0xFF )
10
        i++;
11
    }
12
13
    data[i_over++] = data[i];
14
15
16
  }
17
18
  for(i = i_over; i < 191; i++)
19
    data[i] = 0xFF; //Rest löschen

von Karl H. (kbuchegg)


Lesenswert?

@yalu
schöne Lösung :-)

da kann man dann auch noch das Byte einbauen, welches gefiltert werden 
soll
1
void s(uint8_t d[], uint8_t p, uint8_t n, uint8_t z) {
2
  uint8_t i, j=0, c=0;
3
  for(i=0; i<n; i++)
4
    if((c = (d[i]==p)?0:c+1) <= z)
5
      d[j++] = d[i];
6
  while(j < n)
7
    d[j++] = p;
8
}

von Yalu X. (yalu) (Moderator)


Lesenswert?

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 ;-)

von Klaus W. (mfgkw)


Lesenswert?

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.
:-)

von horst (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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 :-)

von Klaus W. (mfgkw)


Lesenswert?

Bis der zum nächsten Mal stattfindet, kann man den Quelltext wohl
noch einige Zeit optimieren.

von Mark B. (markbrandis)


Lesenswert?

Klaus Wachtler schrieb:
> Bis der zum nächsten Mal stattfindet,

wenn überhaupt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.