2016-03-02 4 views
1

Я пытаюсь добавить оператор деления / в String, который принимает целое число.Оператор отдела на строке

Оператор должен создать массив строк. Размер массива - заданное целое число, а его элементы - подстроки оригинала, которые при объединении по порядку создают исходную строку.

Если длина строки не равномерно делится на целое число, некоторые подстроки должны быть (один символ) длиннее остальных. Ни одна строка не должна отличаться по длине более чем одной, и любые более длинные должны появляться перед любыми более короткими.

Как это:

"This is a relatively long string"/7 
# => ["This ", "is a ", "relat", "ively", " lon", "g st", "ring"] 

Как я могу начать?

+0

Я помню, что для этого был метод Rails или что-то подобное, но я забыл имя метода. Я думаю, что он использует регулярное выражение. – sawa

+0

Пожалуйста, объясните, почему в этом массиве есть строки размером 5. – Aetherus

+0

@Aetherus в массиве должны быть строки 'num', каждая из которых равна одинаковой длине или длине +/- 1, если есть остаток. – Damon

ответ

2

Вы можете использовать рекурсии.

class String 
    def /(n) 
    return [self] if n==1 
    m = (self.size.to_f/n).ceil 
    [self[0...m]].concat(self[m..-1]/(n-1)) 
    end 
end 

str = "This would be a woefully short string had I not padded it out." 

str/7 
    # => ["This woul", "d be a wo", "efully sh", "ort strin", "g had I n", 
    #  "ot padded", " it out."] 


(str/7).map(&:size) 
    #=> [10, 10, 9, 9, 9, 9, 9] 
-2
class String 
    def /(num) 
    partition_size = length/num 
    if length % num == 0 
     scan /.{#{partition_size}}/ 
    else 
     scan /.{#{partition_size},#{partition_size + 1}}/ 
    end 
    end 
end 
+0

это все еще не работает в некоторых случаях – Damon

+0

Пожалуйста, дайте мне угловые шкафы. – Aetherus

+0

'' hellohello "/ 4' разбивает его на 3 вместо 4 – Damon

0

Это мое решение, вроде громоздкого, но O (n) времени.

Позвольте мне знать, если есть какие-то крайние случаи он терпит неудачу для:

class String 
    def /(num) 

    if num > self.length 
     return [] # or whatever, since this is an edge case/can't be done 
    end 

    remainder = self.length % num 
    result = [] 
    substr = "" 

    i = 1 
    while i <= self.length 
     substr += self[i-1] 

     if i % (self.length/num) == 0 
     if remainder > 0 
      substr += self[i] 
      i += 1 
      remainder -= 1 
     end 

     result << substr 
     substr = "" 
     end 

     i += 1 
    end 

    result 
    end 
end 

Edit: Refactored - замененных подмассивов с подстрок

2
class String 
    def /(num) 
     n, rem = self.size.divmod(num) 
     p = 0 
     res = [] 
     rem.times{res << self[p..p+n]; p+=n+1} 
     (num-rem).times{res << self[p...p+n]; p+=n} 
     res 
    end 
end 

p "This is a relatively long string"/7 

["This ", "is a ", "relat", "ively", " lon", "g st", "ring"] 
1

Это будет работать:

class String 
    def /(n) 
    chars.in_groups(n).map(&:join) 
    end 
end 

"This is a relatively long string"/7 
#=> ["This ", "is a ", "relat", "ively", " lon", "g st", "ring"] 

in_groups представляет собой метод, который разбивает Рельсы массив в п групп.

+0

Лучший ответ пока, imo. В Rails, похоже, много классных «чистых Ruby» методов, которые по какой-то причине не были приняты Ruby. –