Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
April 30, 2012 Compute in one pass 3 tokens position | ||||
---|---|---|---|---|
| ||||
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 |
May 01, 2012 Re: Compute in one pass 3 tokens position | ||||
---|---|---|---|---|
| ||||
Posted in reply to bioinfornatics | Le lundi 30 avril 2012 à 14:52 +0200, bioinfornatics a écrit :
> 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
>
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)
sizediiff_t[] countUntil( in char[] seq; char[] tokens ){
bool isSearching = true;
size_t index = 0;
sizediiff_t[] position = new sizediiff_t[](tokens.length);
while (isSearching){
if (index >⁼ seq.length)
isSearching = false;
else if (! find( position, -1) // al token found we can stop;
isSearching = false;
else{
sizediiff_t tmp = countUntil( tokens, [seq[index]]);
if (countUntil( tmp != -1 && position[tmp] != -1)
position[tmp] = index;
index++;
}
}
}
|
May 01, 2012 Re: Compute in one pass 3 tokens position | ||||
---|---|---|---|---|
| ||||
Posted in reply to bioinfornatics | 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]);
}
|
May 03, 2012 Re: Compute in one pass 3 tokens position | ||||
---|---|---|---|---|
| ||||
Posted in reply to bioinfornatics | Le lundi 30 avril 2012 à 14:52 +0200, bioinfornatics a écrit : > 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 > ----------------- 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 = true; size_t index = 0; size_t flag = 0; sizediff_t[string] result; foreach( tok; token) result[tok] = -1; while(isComputing){ if( index >= sequence.length ) isComputing = false; else if( flag == token.length ) isComputing = false; else{ foreach( tok; token){ if( sequence.length - index >= tok.length ){ string currentToken = to!string(sequence[index .. index + tok.length]); if( currentToken in result && result[currentToken] == -1 ){ result[currentToken] = index; flag++; } } } index++; } } return result; } void main( string[] args ){ if( args.length == 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 Re: Compute in one pass 3 tokens position | ||||
---|---|---|---|---|
| ||||
Posted in reply to bioinfornatics | Le lundi 30 avril 2012 à 14:52 +0200, bioinfornatics a écrit :
> 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
>
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 = 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 = true;
size_t index = 0;
size_t flag = 0;
sizediff_t[char[]] result;
foreach( tok; token)
result[tok] = -1;
while(isComputing){
if( index >= sequence.length )
isComputing = false;
else if( flag == token.length )
isComputing = false;
else{
foreach( tok; token){
if( sequence.length - index >= tok.length ){
const(char)[] currentToken = (tok.length > 1) ?
sequence[index .. index + tok.length] : [sequence[index]];
if( currentToken in result && result[currentToken] == -1 ){
result[currentToken] = index;
flag++;
}
}
}
index++;
}
}
return result;
}
void main( string[] args ){
if( args.length == 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 04, 2012 Re: Compute in one pass 3 tokens position | ||||
---|---|---|---|---|
| ||||
Posted in reply to bioinfornatics | 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 |
Copyright © 1999-2021 by the D Language Foundation