www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - findBack: find a needle in a haystack from the back

reply Timothee Cour via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
Is there a more idiomatic/elegant way to achieve the following, while
remaining as efficient as possible?
Same question in the simpler case n==0?

using retro seems inefficient because of all the decodings

// returns the largest suffix of a that contains no more than n times c
string findBack(string a, char c, size_t n=0){
  auto b=cast(immutable(ubyte)[])a;
  auto val=cast(ubyte)c;
  size_t counter=0;
  for(ptrdiff_t i=cast(ptrdiff_t)b.length - 1; i>=0; i--){
    if(b[i]==c){
      if(counter>=n)
        return cast(string)a[i+1..$];
      counter++;
    }
  }
  return a;
}

//unittest{
void test3(){
  auto c='\n';
  string a="abc1\nabc2\nabc3";
  assert(a.findBack(c,0)=="abc3");
  assert(a.findBack(c,1)=="abc2\nabc3");
  assert(a.findBack(c,2)=="abc1\nabc2\nabc3");
  assert(a.findBack(c,3)=="abc1\nabc2\nabc3");
}
Jun 09 2014
next sibling parent "Tobias Pankrath" <tobias pankrath.net> writes:
On Monday, 9 June 2014 at 07:58:25 UTC, Timothee Cour via 
Digitalmars-d-learn wrote:
 Is there a more idiomatic/elegant way to achieve the following, 
 while
 remaining as efficient as possible?
 Same question in the simpler case n==0?

 using retro seems inefficient because of all the decodings

 // returns the largest suffix of a that contains no more than n 
 times c
 string findBack(string a, char c, size_t n=0){
   auto b=cast(immutable(ubyte)[])a;
   auto val=cast(ubyte)c;
   size_t counter=0;
   for(ptrdiff_t i=cast(ptrdiff_t)b.length - 1; i>=0; i--){
     if(b[i]==c){
       if(counter>=n)
         return cast(string)a[i+1..$];
       counter++;
     }
   }
   return a;
 }

 //unittest{
 void test3(){
   auto c='\n';
   string a="abc1\nabc2\nabc3";
   assert(a.findBack(c,0)=="abc3");
   assert(a.findBack(c,1)=="abc2\nabc3");
   assert(a.findBack(c,2)=="abc1\nabc2\nabc3");
   assert(a.findBack(c,3)=="abc1\nabc2\nabc3");
 }
If you are going to cast the string to ubyte[] anyway, why not just do this before using retro?
Jun 09 2014
prev sibling parent =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
 using retro seems inefficient because of all the decodings
Phobos git master just got support for next-gen string processing: https://github.com/D-Programming-Language/phobos/pull/2043 I believe x.byChar.retro is what you want
Jun 09 2014