www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Compute in one pass 3 tokens position

reply bioinfornatics <bioinfornatics fedoraproject.org> writes:
Hi,
I would like to know how compute in on pass 3 tokens position in a
sequence.
curently i do:
File f =3D File( "reader.d", "r" );
scope(exit) f.close();
char[1024] buffer;
char[] content =3D f.rawRead(buffer);
char[sizediff_t] token =3D ['(', '{', ';'];
auto position =3D map!( a =3D> content.countUntil( a ) )( [ ['('], ['{'],
[';'] ] );


if i use reduce instead map the build fail
Apr 30 2012
next sibling parent bioinfornatics <bioinfornatics fedoraproject.org> writes:
Le lundi 30 avril 2012 =C3=A0 14:52 +0200, bioinfornatics a =C3=A9crit :
 Hi,
 I would like to know how compute in on pass 3 tokens position in a
 sequence.
 curently i do:
 File f =3D File( "reader.d", "r" );
 scope(exit) f.close();
 char[1024] buffer;
 char[] content =3D f.rawRead(buffer);
 char[sizediff_t] token =3D ['(', '{', ';'];
 auto position =3D map!( a =3D> content.countUntil( a ) )( [ ['('], ['{'],
 [';'] ] );
=20
=20
 if i use reduce instead map the build fail
=20

Anyone know how to know the position of 3 token in one sequence in one pass? tok1 =3D a tok2 =3D b tok3 =3D c seq =3D blah count me b=3D> 0 a=3D>2 c=3D>5 iterate over sequence if token not yet seen count the number of iteration for know in which column it is located. Example own written on the fly) sizediiff_t[] countUntil( in char[] seq; char[] tokens ){ bool isSearching =3D true; size_t index =3D 0; sizediiff_t[] position =3D new sizediiff_t[](tokens.length); while (isSearching){ if (index >=E2=81=BC seq.length) isSearching =3D false; else if (! find( position, -1) // al token found we can stop; isSearching =3D false; else{ sizediiff_t tmp =3D countUntil( tokens, [seq[index]]); if (countUntil( tmp !=3D -1 && position[tmp] !=3D -1) position[tmp] =3D index; index++; } } }
Apr 30 2012
prev sibling next sibling parent "Era Scarecrow" <rtcvb32 yahoo.com> writes:
On Tuesday, 1 May 2012 at 02:49:19 UTC, bioinfornatics wrote:
 Le lundi 30 avril 2012 à 14:52 +0200, bioinfornatics a écrit :
 Anyone know how to know the position of 3 token in one sequence 
 in one
 pass?

 tok1 = a
 tok2 = b
 tok3 = c
 seq =  blah count me
 b=> 0 a=>2 c=>5
 iterate over sequence if token not yet seen count the number of
 iteration for know in which column it is located. Example own 
 written on
 the fly)

I would say you are trying to way overcomplicated the solution. For simplicity I would use an AA, then a foreach and it will do it in 1 pass (2 if you count the inner ones). I'm not sure if there's a better solution already in phobos, so I can't refer to that :( This could be modified to be more generic so.. //returns AA of tokens that were found and the offset of their first occurrence. int[char] findTokens(const char[] input, char[] tok ...) { int[char] offs; foreach(i, ch; input) { foreach(t; tok) { if (ch == t && t !in offs) offs[t] = i; } } return offs; } unittest { assert(findTokens("blah count me", 'a', 'b', 'c') == ['a':2, 'b' : 0, 'c':5]); }
Apr 30 2012
prev sibling next sibling parent bioinfornatics <bioinfornatics fedoraproject.org> writes:
Le lundi 30 avril 2012 =C3=A0 14:52 +0200, bioinfornatics a =C3=A9crit :
 Hi,
 I would like to know how compute in on pass 3 tokens position in a
 sequence.
 curently i do:
 File f =3D File( "reader.d", "r" );
 scope(exit) f.close();
 char[1024] buffer;
 char[] content =3D f.rawRead(buffer);
 char[sizediff_t] token =3D ['(', '{', ';'];
 auto position =3D map!( a =3D> content.countUntil( a ) )( [ ['('], ['{'],
 [';'] ] );
=20
=20
 if i use reduce instead map the build fail
=20

----------------- CODE ----------------------- import std.stdio; import std.conv; import std.c.process; sizediff_t[string] counter( in char[] sequence, string[] token...) in{ assert(sequence !is null, "Error given sequence is null"); } body{ bool isComputing =3D true; size_t index =3D 0; size_t flag =3D 0; sizediff_t[string] result; foreach( tok; token) result[tok] =3D -1; while(isComputing){ if( index >=3D sequence.length ) isComputing =3D false; else if( flag =3D=3D token.length ) isComputing =3D false; else{ foreach( tok; token){ if( sequence.length - index >=3D tok.length ){ string currentToken =3D to!string(sequence[index .. index + tok.length]); if( currentToken in result && result[currentToken] =3D=3D -1 ){ result[currentToken] =3D index; flag++; } } } index++; } } return result; } void main( string[] args ){ if( args.length =3D=3D 1 ){ writefln( "Usage %s <token1> <token2> <token3> <token4>...", args[0] ); exit(0); } writeln( counter( "This a cool statement such as D is fun. Use it and ot the D power. Oh yeah! Are you ready? Try it!! Have fun.", args[1..$]) ); } ---------------------------------- END CODE ----------------------- $ ./test This D ! ["D":30, "!":74, "This":0] import std.string; if all token is found befoore reach end sequence it stop and save us from some loop it works too if token do not has same length as shown in example
May 03 2012
prev sibling next sibling parent bioinfornatics <bioinfornatics fedoraproject.org> writes:
Le lundi 30 avril 2012 =C3=A0 14:52 +0200, bioinfornatics a =C3=A9crit :
 Hi,
 I would like to know how compute in on pass 3 tokens position in a
 sequence.
 curently i do:
 File f =3D File( "reader.d", "r" );
 scope(exit) f.close();
 char[1024] buffer;
 char[] content =3D f.rawRead(buffer);
 char[sizediff_t] token =3D ['(', '{', ';'];
 auto position =3D map!( a =3D> content.countUntil( a ) )( [ ['('], ['{'],
 [';'] ] );
=20
=20
 if i use reduce instead map the build fail
=20

update code for add attribute poure notrhow nd safe :) ------------------ import std.string; import std.stdio; import std.conv; import std.c.process; /** * searchIndex * search at wich index is located each token in given sequence. * It compute it in one pass. * Returns: * An ssociative array: * key =3D token and value first index where is found * value take -1 if not found in given sequence. */ safe nothrow pure sizediff_t[char[]] searchIndex( in char[] sequence, in char[][] token...) in{ assert(sequence !is null, "Error given sequence is null"); } body{ bool isComputing =3D true; size_t index =3D 0; size_t flag =3D 0; sizediff_t[char[]] result; foreach( tok; token) result[tok] =3D -1; while(isComputing){ if( index >=3D sequence.length ) isComputing =3D false; else if( flag =3D=3D token.length ) isComputing =3D false; else{ foreach( tok; token){ if( sequence.length - index >=3D tok.length ){ const(char)[] currentToken =3D (tok.length > 1) ? sequence[index .. index + tok.length] : [sequence[index]]; if( currentToken in result && result[currentToken] =3D=3D -1 ){ result[currentToken] =3D index; flag++; } } } index++; } } return result; } void main( string[] args ){ if( args.length =3D=3D 1 ){ writefln( "Usage %s <token1> <token2> <token3> <token4>...", args[0] ); exit(0); } writeln( searchIndex( "This a cool statement such as D is fun. Use it and got the D power. Oh yeah! Are you ready? Try it!! Have fun.", args[1..$]) ); }
May 03 2012
prev sibling parent "Jesse Phillips" <Jessekphillips+D gmail.com> writes:
On Monday, 30 April 2012 at 12:53:16 UTC, bioinfornatics wrote:
 Hi,
 I would like to know how compute in on pass 3 tokens position 
 in a
 sequence.
 curently i do:
 File f = File( "reader.d", "r" );
 scope(exit) f.close();
 char[1024] buffer;
 char[] content = f.rawRead(buffer);
 char[sizediff_t] token = ['(', '{', ';'];
 auto position = map!( a => content.countUntil( a ) )( [ ['('], 
 ['{'],
 [';'] ] );


 if i use reduce instead map the build fail

It doesn't give your answer directly, but I requested that countUntil take ranges: http://d.puremagic.com/issues/show_bug.cgi?id=5507 And made such a countUntil so that I could use it: https://github.com/JesseKPhillips/JPDLibs/blob/csvoptimize/csv/newadds.d
May 04 2012