Лучший способ создать строку, содержащую несколько копий другой строки - PullRequest
5 голосов
/ 11 января 2010

Я хочу создать функцию, которая будет принимать строку и целое число в качестве параметров и возвращать строку, содержащую строковый параметр, повторенный указанное количество раз.

Например:

std::string MakeDuplicate( const std::string& str, int x )
{
    ...
}

Вызов MakeDuplicate( "abc", 3 ); вернет "abcabcabc".

Я знаю, что могу сделать это, просто зацикливаясь x раз, но я уверен, что должен быть лучший способ.

Ответы [ 4 ]

19 голосов
/ 11 января 2010

Я не вижу проблемы с зацикливанием, просто сначала сделайте резерв:

std::string MakeDuplicate( const std::string& str, int x )
{
    std::string newstr;
    newstr.reserve(str.length()*x); // prevents multiple reallocations

    // loop...

    return newstr;
}
7 голосов
/ 11 января 2010

В какой-то момент это должен быть цикл.Возможно, вы сможете скрыть зацикливание в какой-то причудливой языковой фразеологии, но в конечном итоге вам придется зацикливаться.

4 голосов
/ 11 января 2010

Для маленьких «х» простой цикл ваш друг. Для больших 'x и относительно коротких' str 'мы можем придумать «более разумное» решение, повторно используя уже конкатенированную строку.

std::string MakeDuplicate( const std::string& str, unsigned int x ) {

  std::string newstr;
  if (x>0) {
    unsigned int y = 2;
    newstr.reserve(str.length()*x);  
    newstr.append(str);
    while (y<x) {
      newstr.append(newstr);
      y*=2;
    }
    newstr.append(newstr.c_str(), (x-y/2)*str.length());
  }
  return newstr;
}

Или что-то в этом роде: o) (Я думаю, что это можно написать более хорошим способом, но идея есть).

РЕДАКТИРОВАТЬ: я сам был проинструктирован и провел несколько тестов, сравнивая три решения на моем ноутбуке с визуальной студией (версия с повторным использованием, простой цикл с предварительным распределением, простой копирование и цикл 1 без предварительного выделения). Ожидаемые результаты: для малых x (<10) версия предварительного выделения обычно самая быстрая, никакое предварительное распределение не было чуть-чуть медленнее, для большего x ускорение версии «повторного использования» действительно существенно (log n против n сложности). Хорошо, я просто не могу вспомнить ни одной реальной проблемы, которая могла бы ее использовать: o) </p>

2 голосов
/ 11 января 2010

Существует альтернатива циклу, который называется рекурсия , и рекурсии хвостовая рекурсия - самый хороший вариант, поскольку теоретически вы можете сделать это до конца времени - просто как петля: D

ps, хвостовая рекурсия часто является синтаксическим сахаром для цикла - однако в случае процедурных языков (C ++) компилятор, как правило, теряется, поэтому хвостовая рекурсия не оптимизируется, и вы можете исчерпать память (но если вы написали рекурсию, которой не хватает памяти, чем у вас есть большие проблемы): D

больше голосов, пожалуйста !!

рекурсия явно не является конструкцией, используемой в информатике для той же работы, что и цикл

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...