Double Space
April 4, 2017
Our algorithm makes two passes over the input; the first pass counts spaces, then a new string is allocated, and the second pass copies, adding spaces as it goes:
(define (double-space oldstr)
(define (space? str idx)
(char=? (string-ref str idx) #\space))
(let ((oldlen (string-length oldstr)))
(do ((oldidx 0 (+ oldidx 1))
(count 0 (+ count (if (space? oldstr oldidx) 1 0))))
((= oldidx oldlen)
(let* ((newlen (+ oldlen count))
(newstr (make-string newlen #\space)))
(do ((oldidx 0 (+ oldidx 1))
(newidx 0 (+ newidx (if (space? newstr newidx) 2 1))))
((= oldidx oldlen) newstr)
(string-set! newstr newidx (string-ref oldstr oldidx))))))))
Here are some examples:
> (double-space "hello") "hello" > (double-space "hello hello") "hello hello" > (double-space "hello hello") "hello hello" > (double-space "hello hello") "hello hello" > (double-space "hello hello hello") "hello hello hello" > (double-space " hello ") " hello " > (double-space "") "" > (double-space " ") " " > (double-space " ") " " > (double-space " ") " "
There are other ways to do that. Here we convert the string to a list of characters, make a single pass through the list copying two spaces wherever one is found, then reverse the list and convert back to a string:
(define (double-space str)
(let loop ((xs (string->list str)) (zs (list)))
(if (null? xs) (list->string (reverse zs))
(if (char=? (car xs) #\space)
(loop (cdr xs) (cons #\space (cons #\space zs)))
(loop (cdr xs) (cons (car xs) zs))))))
All the test cases produce identical results. You can run the program at http://ideone.com/YoEiw9.
As a perl programmer this one is trivial:
sub ds{shift=~s{ }{ }rg}if you don’t want to use s{} could do
sub ds{join'',map{$_,' 'eq$_?' ':''}split'',shift}Clojure:
(defn dup_space [input] (apply str (map (fn [c] (if(= \space c) " " (str c))) input)))Also not too difficult in Python.
def double_space(txt): return txt.replace(" ", " ")javascript:
function double_space(txt){
return txt.replace(/ /g,’ ‘);
}
https://pastebin.com/embed_js/MQchRuyU
Read-write Scheme.
(setlocale LC_ALL "") ;sigh (this is in guile 2.0.9) (define (double-space-port in out) (let ((o (read-char in))) (or (eof-object? o) (begin (write-char o out) (case o ((#\space) (write-char o out))) (double-space-port in out))))) (define (double-spaced-string s) (let ((out (open-output-string))) (double-space-port (open-input-string s) out) (get-output-string out))) (write (double-spaced-string "Taas mennään. Ja äätkin näkyy!")) (newline)Read-write Python.
import io def double_space_io(inio, outio): while True: o = inio.read(1) if not o: return outio.write(o) if o in ' ': outio.write(o) def double_space_str(s): outio = io.StringIO() double_space_io(io.StringIO(s), outio) return outio.getvalue() print(repr(double_space_str("Taas mennään. Ja äätkin näkyy!")))Took the Python generator approach. We can feed the double_space generator with characters and they get doubled up.
MUMPS:
r !,word,! f i=1:1:$l(word,” “) w:i>1 ” ” w $p(word,” “,i)
hello, world!
hello, world!
A Haskell version. (Note: cat -e prints a ‘$’ at the end of a line.)
Nothing difficult for Ruby
`def double_space(string)
return string.gsub(/\s/, ‘ ‘)
end
puts double_space(“hello word”)`
dup (' ':xs) = ' ':' ':dup xs dup ( x :xs) = x :dup xs dup [] = []for non streaming algorithms the former maybe slow and memory expensive then, we can use ByteStrings (lazy or strict, depends)
{-# LANGUAGE OverloadedStrings #-} import qualified Data.ByteString.Lazy.Char8 as BS dup' = BS.concatMap d where d ' ' = " " d x = BS.singleton x[…] how easy your favorite programming language makes it to work with strings. The problem is to double every blank in a string. That’s pretty simple but some languages make you deal with string allocation or perhaps, in […]
Powershell makes it easy:
Function Set-DoubleSpace ($a) {$a-replace” “,” “}
or from STDIN
(read-host)-replace” “,” “
in Java:
public String doubleSpaces(String in) {
return in.replace(” “, ” “);
}