Sfida di programmazione JSL: conversione da stringa di Y e N a matrice di 1 e 0 e viceversaCiao programmatori JSL,
Ho avuto un piccolo problema come parte di un'applicazione più ampia e ho pensato di condividerlo con te e vedere se c'è un modo per farlo meglio/più efficiente.
Fondamentalmente ho un vettore di 1 e 0 (cioè [1, 1, 0, 0, 1]) che devo convertire in una stringa di Y e N (cioè "YYNNY").Quindi devo fare il contrario, cioè convertire una stringa di Y e N in un vettore di 1 e 0.
Ecco le mie funzioni veloci e sporche: vediamo se riesci a inventare qualcosa che va oltre le mie deboli capacità cerebrali!
// Convert a vector of 1s and 0s to a string with no separators
matrix_10_to_yn = function({matrix_10}, {default local},
yn_txt = "";
if (nrows(matrix_10) > 0,
// Strip out square brackets and commas
yn_txt = substitute(char(matrix_10), "[", "", "]", "", ", ", "");
// Now convert 1s to Y and 0s to N
yn_txt = substitute(yn_txt, "1", "Y", "0", "N");
);
yn_txt;
);
// Convert a YN string with no separators to a vector of 1s and 0s
yn_to_matrix_10 = function({yn_txt}, {default local},
n = length(yn_txt);
matrix_10 = j(n, 1, 0);
for (i = 1, i <= n, i++,
if (substr(yn_txt, i, 1) == "Y",
matrix_10[i] = 1;
);
);
matrix_10;
);
<BR />// Test thing out
a = yn_to_matrix_10("YYYNNNN"); show(a);
b = matrix_10_to_yn(a); show(b);
c = yn_to_matrix_10(""); show(c);
d = matrix_10_to_yn(c); show(d);Ri: Sfida di programmazione JSL: conversione da stringa di Y e N a matrice di 1 e 0 e viceversaSoluzioni così interessanti.Non posso credere alla varietà di approcci utilizzati per risolvere questo problema relativamente semplice.Grazie ancora a tutti.
Ri: Sfida di programmazione JSL: conversione da stringa di Y e N a matrice di 1 e 0 e viceversaQueste sono tutte soluzioni molto interessanti. Il PMROZ ha sottolineato che avevo letto male che il secanrio dovesse iniziare con un elenco. Ha chiesto la mia soluzione rivista.Di seguito converte un elenco o una stringa di YN in un vettore di 10 e un vettore di 10 in una stringa di YN.
Per essere coerente con il mio post precedente, ho appena convertito la stringa in un elenco con la funzione parole() utilizzando un delimitatore di stringa vuoto.
exmat = J(25,1, RandomInteger(0,1));
exlst = Insert({}, {"Y", "N"}[2-exmat]);
exstr = ConcatItems(Insert({}, {"Y", "N"}[2-exmat]), "");
convert_yn = Function({usr}, {rslt=empty(), ynList ={"Y","N"} },
if(IsMatrix(usr),
rslt = ConcatItems(insert({},ynList[2-usr]),"")
, //else
IsList(usr),
rslt = J(nitems(usr),1, 1);
rslt[loc(usr,"N")]=0
, //else
IsString(usr),
rslt = J(length(Trim(usr)),1,1);
rslt[loc(words(usr,""),"N")]=0
); //end if
rslt
); //end Function
show(exmat, convert_yn(exmat), exlst, convert_yn(exlst), exstr, convert_yn(exstr) );Ri: Sfida di programmazione JSL: conversione da stringa di Y e N a matrice di 1 e 0 e viceversaUtilizzo una funzione generica 'mapply' nella maggior parte dei progetti, quindi normalmente avrei bisogno solo delle ultime due righe:
Names Default to here(1);
// Utility function to make for loops, combo 'map' and 'apply'
// this is a 'fake' map/apply function because it allows side
// effects (like apply) and it also returns a value (like map)
mapply = function( {x, foo, arg1 = "__missing", arg2 = "__missing"}, { i, r = {}, x, foo, arg1, arg2, arg1missing, arg2missing },
if( N Items( x ) < 1,
return({}), //empty list supplied, return an empty list
for( i = 1, i <= N Items(x), i++,
arg1missing = 0; arg2missing = 0;
If( type(arg1) == "String", If( arg1 == "__missing", arg1missing = 1 ) );
If( type(arg2) == "String", If( arg2 == "__missing", arg2missing = 1 ) );
if(
arg1missing == 1,
r = Insert( r, foo( x[i] ) ),
arg2missing == 1,
r = Insert( r, foo( x[i], arg1 ) ),
r = Insert( r, foo( x[i], arg1, arg2 ) )
)
)
);
return(r);
);
// Solution:
str = "YYYNNNNYYNY";
(numbers = mapply( words(str,""), function( {x}, if( x=="Y", 1, 0) ) ) )
mapply( as list(numbers), function( {x}, if( x==1,"Y", "N") ) )Ri: Sfida di programmazione JSL: conversione da stringa di Y e N a matrice di 1 e 0 e viceversa@pmroz ,
Ecco la mia interpretazione/tentativo in merito. Grazie per aver proposto questa interessante sfida. So che sto usando un ciclo che non so se si ridimensionerà bene su matrici di grandi dimensioni, ma ho pensato che alcuni altri nella comunità possano trovare un modo più veloce.
Clear Log(); Clear Globals();
ex = Associative Array({1,0} ,{"Y", "N"});
Test = [1,0, 1, 1, 1, 0, 0, 1, 0, 1];
Res = {};
for(i = 1, i <= N Rows(Test), i++,
Insert Into(Res, ex << Get Value(Test[i]));
);
Show(Res);
Ri: Sfida di programmazione JSL: conversione da stringa di Y e N a matrice di 1 e 0 e viceversae ora devo studiare la funzione design()!
Ri: Sfida di programmazione JSL: conversione da stringa di Y e N a matrice di 1 e 0 e viceversaWow, questi sono fantastici.Ringrazia tutti!
Ri: Sfida di programmazione JSL: conversione da stringa di Y e N a matrice di 1 e 0 e viceversaOps, non ho visto la risposta di Craig... la sua versione è migliore, credo.
Ri: Sfida di programmazione JSL: conversione da stringa di Y e N a matrice di 1 e 0 e viceversapuoi eseguire la conversione da stringa a matrice in una singola riga utilizzando Char to Blob e Blob to Matrix. Il mio contributo:
names default to here(1);
a=[1,0, 1, 1, 1, 0, 0, 1, 0, 1];
b="YNYYYNNYNY";
f_YNString_to_IndicatorVector=Function({s},
blob to matrix(char to blob(d),"int", 1, "little", 1)==89;
);
f_IndicatorVector_to_YNString=Function({v},{vv},
vv=As List(v);
vv[loc(v)]="Y";
vv[loc(!v)]="N";
concat items(vv,"");
);
show(a);
show(b);
Show(f_YNString_to_IndicatorVector(b));
Show(f_IndicatorVector_to_YNString(a));
Show(f_IndicatorVector_to_YNString(f_YNString_to_IndicatorVector(b)));
Ri: Sfida di programmazione JSL: conversione da stringa di Y e N a matrice di 1 e 0 e viceversa
Ciò non si estenderà a tre valori o valori mancanti/errati senza uno sforzo aggiuntivo. Converte string-blob-matrix ed esegue il rilevamento Y e N utilizzando il numero del carattere ASCII nella matrice. Alle funzioni BlobToMatrix e MatrixToBlob viene detto di utilizzare numeri interi little-endian da 1 byte. L'endianness non è fondamentale per i numeri da 1 byte, funziona altrettanto bene. Dipende dai caratteri che hanno rappresentazioni di un byte.
source = "YYNNYQ";
// if you are uncomfortable with hard coded constants...
Yvalue = Blob To Matrix( Char To Blob( "Y" ), "int", 1, "little" )[1]; // 89
Nvalue = Blob To Matrix( Char To Blob( "N" ), "int", 1, "little" )[1]; // 78
// forward
numbers = Blob To Matrix( Char To Blob( source ), "int", 1, "little" ) == Yvalue;
// reverse
string = Blob To Char( Matrix To Blob( Nvalue + numbers * (Yvalue - Nvalue), "int", 1, "little" ) );
// display
Show( source, numbers, string );
fonte = "YYNNYQ";
numeri = [1, 1, 0, 0, 1, 0];
stringa = "YYNNYN";
Ri: Sfida di programmazione JSL: conversione da stringa di Y e N a matrice di 1 e 0 e viceversaUn altro!!
Names Default to here(1);
yto1 = function({str},
{DEFAULT LOCAL},
list = words(str, "");
design(list, {"Y"});
);
oneToY = function({mat},
list = substitute(as list(mat), 1, "Y", 0, "N");
Concat items(list, "");
);
str = "YYYNNNNYYNY";
nums = yto1(str);
show(nums);
str2 = oneToY(nums);
show(str2, str2==str);Ri: Sfida di programmazione JSL: conversione da stringa di Y e N a matrice di 1 e 0 e viceversaQualunque cosa funzioni, funziona!Ecco un'alternativa.
exmat = J(25,1, RandomInteger(0,1));
exlst = Insert({}, {"Y", "N"}[2-exmat]);
convert_yn = Function({usr}, {rslt, ynList ={"Y","N"} },
if(IsMatrix(usr),
rslt = insert({},ynList[2-usr])
, //else
rslt = J(nitems(usr),1, 1);
rslt[loc(usr,"N")]=0
); //end if
rslt
); //end Function
show(exmat, convert_yn(exmat), exlst, convert_yn(exlst));