Run-length encoding: Difference between revisions
Content added Content deleted
(Updated two of the four D versions) |
(Updated two D versions) |
||
Line 724: | Line 724: | ||
=={{header|D}}== |
=={{header|D}}== |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
===Basic Imperative Version=== |
===Basic Imperative Version=== |
||
<lang d>import std.stdio, std.array, std.conv; |
<lang d>import std.stdio, std.array, std.conv; |
||
Line 774: | Line 787: | ||
writeln("Encoded: ", encoded); |
writeln("Encoded: ", encoded); |
||
assert(txt == decode(encoded)); |
assert(txt == decode(encoded)); |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
}</lang> |
}</lang> |
||
===UTF String Version=== |
===UTF String Version=== |
||
D's native string is utf-encoded. This version work for utf string. This code use a [[Variable-length_quantity|Variable-length Quantity]] [[Variable-length_quantity#D|module]]. |
D's native string is utf-encoded. This version work for utf string. This code use a [[Variable-length_quantity|Variable-length Quantity]] [[Variable-length_quantity#D|module]]. |
||
<lang d>import std.stdio ; |
<lang d>import std.stdio, std.conv, std.utf, std.string; |
||
import |
import vlq; |
||
import std.utf ; |
|||
import std.string ; |
|||
import vlq ; |
|||
struct RLE { // for utf string |
struct RLE { // for utf string |
||
ubyte[] encoded |
ubyte[] encoded; |
||
RLE encode(const string s) { |
RLE encode(const string s) { |
||
validate(s) |
validate(s); // check if s is well-formed utf, throw if not |
||
encoded.length = 0 |
encoded.length = 0; // reset |
||
if(s.length == 0) return this |
if (s.length == 0) return this; // empty string |
||
string last |
string last; |
||
VLQ count |
VLQ count; |
||
for(int i = 0 |
for (int i = 0; i < s.length; ) { |
||
auto k = s.stride(i) |
auto k = s.stride(i); |
||
auto ucode = cast(string)s[i..i+k] |
auto ucode = cast(string)s[i .. i+k]; |
||
if(i == 0) last = ucode |
if (i == 0) last = ucode; |
||
if(ucode == last) |
if (ucode == last) |
||
count++ |
count++; |
||
else { |
else { |
||
encoded ~= count.toVLQ ~ cast(ubyte[]) |
encoded ~= count.toVLQ ~ cast(ubyte[])last; |
||
last = ucode |
last = ucode; |
||
count = 1 |
count = 1; |
||
} |
} |
||
i += k |
i += k; |
||
} |
} |
||
encoded ~= VLQ(count).toVLQ ~ cast(ubyte[]) |
encoded ~= VLQ(count).toVLQ ~ cast(ubyte[])last; |
||
return this |
return this; |
||
} |
} |
||
int opApply(int delegate(ref ulong c, ref string u) dg) { |
int opApply(int delegate(ref ulong c, ref string u) dg) { |
||
VLQ count |
VLQ count; |
||
string ucode |
string ucode; |
||
for(int i = 0 ; i < encoded.length ;) { |
|||
for (int i = 0; i < encoded.length; ) { |
|||
auto k = count.extract(encoded[i .. $]); |
|||
i += k; |
|||
if (i >= encoded.length) |
|||
throw new Exception("not valid encoded string"); |
|||
k = stride(cast(string) encoded[i .. $], 0); |
|||
if (k == 0xff) // not valid utf code point |
|||
throw new Exception("not valid encoded string"); |
|||
ucode = cast(string)encoded[i .. i+k].dup; |
|||
dg(count.value, ucode); |
|||
i += k; |
|||
} |
|||
⚫ | |||
return 0; |
|||
⚫ | |||
string toString() { |
string toString() { |
||
string res |
string res; |
||
foreach(ref i, s ; this) |
foreach (ref i, s ; this) |
||
if(indexOf( |
if (indexOf("0123456789#", s) == -1) |
||
res ~= |
res ~= text(i) ~ s; |
||
else |
else |
||
res ~= |
res ~= text(i) ~ '#' ~ s; |
||
return res |
return res; |
||
} |
} |
||
string decode() { |
string decode() { |
||
string res |
string res; |
||
foreach(ref i, s |
foreach (ref i, s; this) |
||
res ~= repeat(s, cast(uint)i) |
res ~= repeat(s, cast(uint)i); |
||
return res |
return res; |
||
} |
} |
||
} |
} |
||
void main() { |
void main() { |
||
RLE r |
RLE r; |
||
auto s = "尋尋覓覓冷冷清清淒淒慘慘戚戚\nWWWWWWWWWWWWBWWWWWWWWWWW" |
auto s = "尋尋覓覓冷冷清清淒淒慘慘戚戚\nWWWWWWWWWWWWBWWWWWWWWWWW" ~ |
||
"WBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW\n" |
"WBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW\n" ~ |
||
"11#222##333" |
"11#222##333"; |
||
auto f = File("display.txt", "w") |
auto f = File("display.txt", "w"); |
||
f.writeln(s) |
f.writeln(s); |
||
r.encode(s) |
r.encode(s); |
||
f.writefln("-----\n%s\n-----\n%s", r, r.decode) |
f.writefln("-----\n%s\n-----\n%s", r, r.decode); |
||
auto sEncoded = RLE.init.encode(s).encoded ; |
auto sEncoded = RLE.init.encode(s).encoded ; |
||
assert(s == RLE(sEncoded).decode , "Not work") |
assert(s == RLE(sEncoded).decode , "Not work"); |
||
}</lang> |
}</lang> |
||