This is the Julia implementation of the anagram program. The problem and the solution is described in the main anagram article. Do read that article first.
Also, you may find the C++ article helpful, since it describes member data and functions in some detail, not repeated here. This article describes only the differences between the C++ implementation and this implementation.
The Julia implementation is similar, almost identical, to the most other implementations; the differences are mostly syntactical.
The source code
using Printf; MINIMUM = 3; comparisons = 0; #------------------------------------------------------------------------ Word mutable struct Word offset :: Int; value :: String unified :: String end function print(this :: Word) @printf("%4d %s %s\n", this.offset, this.value, this.unified); end function get_unified(s :: String) tmp = Vector{Char}(s); sort!(tmp); return String(tmp); end function isless(a :: Word, b :: Word) :: Bool # comparisons = comparisons + 1; if (a.unified < b.unified) return true; elseif (a.unified > b.unified) return false; else return a.offset < b.offset; end end #------------------------------------------------------------------------ AnagramFinder mutable struct AnagramFinder len :: Int; words :: Array{Word, 1}; accepted :: Array{Word, 1}; low_offset :: Int; function AnagramFinder(text :: String, len :: Int) #--- Constructor this = new(len, Word[], Word[], 0); last :: Int = length(text) - len + 1; for n = 1:last w :: String = text[n:(n+len-1)]; push!(this.words, Word(n-1, w, get_unified(w))); end return this; end end function print_one_result(this :: AnagramFinder) @printf("%3u:", length(this.accepted)); for it in this.accepted @printf(" %4d:%s", it.offset, it.value); end @printf("\n"); end function add_candidate(this :: AnagramFinder, cand :: Word) if (cand.offset < this.low_offset) return; end for it in this.accepted if (it.value == cand.value) return; end end push!(this.accepted, cand); this.low_offset = cand.offset + this.len; end function add_range(this :: AnagramFinder, first :: Int, last :: Int) if (last-first+1 >= MINIMUM) this.accepted = Array{Char, 1}(); this.low_offset = 0; for n = first:last add_candidate(this, this.words[n]); end if (length(this.accepted) >= MINIMUM) print_one_result(this); end end end function find_all(this :: AnagramFinder) sort!(this.words, lt = isless); first :: Int = 1; for n = 2:length(this.words) if (this.words[n].unified != this.words[first].unified) add_range(this, first, n-1); first = n; end end add_range(this, first, length(this.words)); end function read_text() :: String tmp :: Array{Char, 1} = []; sizehint!(tmp, 500*512); while (! eof(stdin)) ch :: Char = uppercase(read(stdin, Char)); if (isletter(ch)) push!(tmp, ch); end end return String(tmp); end #------------------------------------------------------------------------ main function main(argc :: Int, argv :: Array{String, 1}) from :: Int = (argc > 0) ? parse(Int, argv[1]) : 6; to :: Int = (argc > 1) ? parse(Int, argv[2]) : from; text :: String = read_text(); for len = from:to finder :: AnagramFinder = AnagramFinder(text, len); @printf("%slen = %d\n", (len > from) ? "\n" : "", len); find_all(finder); end @printf("string length = %5d, comparisons = %s\n", length(text), comparisons > 0 ? comparisons : "****"); end main(length(ARGS), ARGS);
You can reach me by email at “lars dash 7 dot sdu dot se” or by telephone +46 705 189090