Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » Rätselecke » mal was anderes

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
02.12.2004, 02:02 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


so zu schreiben ist folgende funktion....

angenommen man hat eine quadratische matrix m mit der kantenlänge einer 2erpotenz zeilenweise in einem Array abgespeichert...

diese matrix soll nach einem ganz bestimmten prinzip durchalufen werden und zwar immer erst links oben dann rechts oben dann links unten und dann wieder rechts oben... diese struktur setzt sich immer grösser werdend durch die ganze matrix fort...

also nehmen wir an wir haben eine 2x2 matrix dann soll die wie folgt durchlaufen werden

C++:
0 1
2 3



bei einer 4*4 matrix sieht das dann so aus


C++:
00 01 04 05
02 03 06 07
08 09 12 13
10 11 14 15



8*8 dann so


C++:
00 01 04 05 16 17 20 21
02 03 06 07 18 19 22 23
08 09 12 13 24 25 28 29
10 11 14 15 26 27 30 31
32 33 36 37 48 49 52 53
34 35 38 39 50 51 54 55
40 41 44 45 56 57 60 61
42 43 46 47 58 59 62 63



ist also quasi immer diese nach recht dann anch links unten und wieder nach rechts muster das sich immer weiter aufbläht je grösser die matrix wird....

sei n schritt in dem man sich gerade beim durchlaufen der matrix befindet (also z.b. wenn n=49 ist, ist man in der matrix gerade an zeile 4 und spalte 5...

so und zu schreiben sind folgende funktionen...


C++:
size_t f1(size_t p);
size_t f2(size_t p);
size_t f3(size_t x,size_t y);


f1 und f2 bekommen jeweils die position in der man sich im n.ten schritt befindet (n fängt bei 0 an) und liefern die reihe bzw die spalte in der man sich innerhalb der matrix gerade befindet... um nochmal auf das beispiel zu kommen.... übergibt man f1 49 soll es zeile 4 liefern und übergibt man f2 49 soll sie spalte 5 liefern...

f3 ist dann die umkehrfunktion, zu einer übergebenen reihe und spalte soll angeben werden bei welchem n. schritt man sich gerade befindet....

golfLösungen werden bevorzugt angenommen
--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 02.12.2004 um 02:03 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
02.12.2004, 09:30 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


ups hab ich das wieder scheisse erklärt... mus die uhrzeit gewesen sein und ein fehlerchen hat sich auch eingeschlichen


Zitat:

diese matrix soll nach einem ganz bestimmten prinzip durchalufen werden und zwar immer erst links oben dann rechts oben dann links unten und dann wieder rechts oben... diese struktur setzt sich immer grösser werdend durch die ganze matrix fort...


also nochmal der zyklus den es zu durchlaufen gibt ist links oben, rechts oben, links unten, rechts unten.... (und natürlich nicht rechts oben, sorry)...

wenn die matrix grösser ist als 2x2 halbiert man quasi einfach die matrix vertikal und horizontal und erhält dann 4 untermatrizen insgesammt und jede selbst von ihnen auch in diesem rechts oben, links oben, rechts unten, links unten prinzip zu durchlaufen sind... man muss also so lange runterbrechen bis man auf 2*2 matrizen kommt.
das mit dem runterbrechen funktioniert deshalb weil die matrix laut annahme immer eine kantenlänge einer 2er potenz hat....
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
02.12.2004, 23:26 Uhr
(un)wissender
Niveauwart


So, hier mal eine Lösung. Vermutlich recht aufwendig, aber mir viel so ad hoc nichts besseres ein.


C++:
#include <iostream>
#include <cstddef>
#include <cmath>

//Von mir selber...ca. 300 Zeilen, aber die Funktionsweise sollte klar sein.
#include "TwoDArray.hpp"

const std::size_t matrixSize = 8;

std::size_t f1(std::size_t p);
std::size_t f2(std::size_t p);
std::size_t f3(std::size_t x, std::size_t y);
void getRowAndColForPos(std::size_t p, std::size_t &row, std::size_t &col);

int main()
{
    stdEx::TwoDArray<std::size_t> matrix(matrixSize, matrixSize);
    for(std::size_t i = 0; i < matrixSize * matrixSize; ++i)
    {
        std::size_t row = f1(i), col = f2(i);
        matrix(row, col) = f3(row, col);
    }
    
    for(std::size_t i = 0; i < matrixSize; ++i)
    {
        for(std::size_t j = 0; j < matrixSize; ++j)
        {
            std::cout << matrix(i,j) << " | ";
        }
        std::cout << std::endl;
    }
}

std::size_t f1(std::size_t p)
{
    std::size_t row, col;
    getRowAndColForPos(p, row, col);
    return row;
}

std::size_t f2(std::size_t p)
{
    std::size_t row, col;
    getRowAndColForPos(p, row, col);
    return col;
}

//Sehr primitiv, hatte keine Lust mehr, vielleicht denke ich mir da noch was...
std::size_t f3(std::size_t x, std::size_t y)
{
    std::size_t row, col;
    for(std::size_t i = 0; i < matrixSize * matrixSize; ++i)
    {
        getRowAndColForPos(i,row, col);
        if(row == x && col == y)
        {
            return i;
        }
    }
}

void getRowAndColForPos(std::size_t p, std::size_t &row, std::size_t &col)
{
    std::size_t lowerBorder = 0, upperBorder = matrixSize * matrixSize,
                factor = matrixSize / 2,
                diff = upperBorder - lowerBorder;

    row = col = 0;
    
    while(diff >= 4)
    {
        std::size_t granu = diff / 4;

        if(p < lowerBorder + 1 * granu)
        {
            upperBorder = lowerBorder + 1 * granu;
        }
        else if(p < lowerBorder + 2 * granu)
        {
            upperBorder = lowerBorder + 2 * granu;
            lowerBorder = lowerBorder + 1 * granu;
            col += granu / factor;
        }
        else if(p < lowerBorder + 3 * granu)
        {
            upperBorder = lowerBorder + 3 * granu;
            lowerBorder = lowerBorder + 2 * granu;
            row += granu / factor;
        }
        else
        {
            lowerBorder = lowerBorder + 3 * granu;
            col += granu / factor;
            row += granu / factor;
        }

        factor /= 2;
        diff = upperBorder - lowerBorder;
    }
}


--
Wer früher stirbt ist länger tot.

Dieser Post wurde am 02.12.2004 um 23:27 Uhr von (un)wissender editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
03.12.2004, 01:47 Uhr
mmc20
puss in boots


hallo,
ich hab sowas lange nicht mehr gemacht, und mit bits eigentlich seit meinen assemblerzeiten nicht mehr gerechnet...
die lösung ist eigentlich einfach da sich die spalte aus den geraden bits (6|4|2|0) und die zeile aus den ungeraden bits (7|5|3|1) der position zusammen setzt. (jetzt mal von einer 8*8 matrix ausgegangen) also brauch man sich nur die entsprechenden bits aus der position "klauen" und schon hat man zeile und spalte

C++:
// ...
// DWORD pos -> ist die matrixposition
// dimMatrix -> ist die spalten/zeilen anzahl

DWORD spalte=0, zeile=0;
for ( int i = 0; i < dimMatrix; i++ ) {
     spalte |= pos & (DWORD)pow(2, i);
     pos >>= 1;
     zeile |= pos & (DWORD)pow(2, i);
}
// ...


hab das jetzt aber nur so hin geschrieben, also ungetestet !
soll ja auch keine lösung sein, sondern nur ein ansatz...

Dieser Post wurde am 03.12.2004 um 01:50 Uhr von mmc20 editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
03.12.2004, 02:36 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


mmc hat das einfache prinzip dahinter verstanden
ich fand das war ne super kopfnuss hab selber ne weile dran gebastelt...
habs selber auch noch nicht gegolft aber im ersten ansatz bin ich auf sowas gekommen...
man brauch also dir matrix gar nicht dient nur zur veranschaulichung...

C++:
size_t f1(size_t pos){
    size_t i,rv=0;
    for(i=0;i<8*sizeof(size_t);i+=2)    
        rv|=(pos&(1<<i))>>i/2;
    return rv;
}

size_t f2(size_t pos){
    size_t i,rv=0;
    for(i=1;i<8*sizeof(size_t);i+=2)    
        rv|=(pos&(1<<i))>>(i+1)/2;
    return rv;
}


--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 03.12.2004 um 02:36 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
03.12.2004, 09:01 Uhr
(un)wissender
Niveauwart


Nicht schlecht, bin ich nicht drauf gekommen!
Aber ich brauche für das Suchen der Zeilen Spalten/Spalten nur log4(sizeMatrix*sizeMatrix) Schritte. Also weniger als ihr.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
03.12.2004, 10:53 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


@(un)wissender
ich schaffs sogar mit log2(sizeMatrix)
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
03.12.2004, 13:06 Uhr
(un)wissender
Niveauwart


Den Code mußt du aber noch zeigen...
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
03.12.2004, 13:48 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


steht doch schon oben... im moment geh ich den ganzen size_t typ durch... wen ich mich darauf beschränke die anzahl der benötigten bits zu verweden (bei einer 8x8) Matrix dann in höhe und tiefe jeweils 8 bin ich doch bei log2 da ic hnur 3 duchgänge (bits) brauche (die führenden nullen hatte ich bei obigen code nur mal aus faulheit mitgenommen da das so unabhängig von der grösse der matrix ist (so die matrix nicht grösser wird als der size_t typ darstellen kann, dann würde da ja sowie alles den bach runtergehen)
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
03.12.2004, 14:17 Uhr
(un)wissender
Niveauwart



Zitat von Windalf:

@(un)wissender
ich schaffs sogar mit log2(sizeMatrix)



log2(sizeMatrix) == log4(sizeMatrix*sizeMatrix) würde ich mal behaupten...
--
Wer früher stirbt ist länger tot.

Dieser Post wurde am 03.12.2004 um 14:20 Uhr von (un)wissender editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ Rätselecke ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: