Эффективный способ создания массива / вектора строк и определения длины всех строк в нем - PullRequest
1 голос
/ 31 марта 2020

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

У меня есть какое-то дурное представление о функции, но как я эффективно отправил ей массив / вектор строк и размер всех эти строки объединены. Например, функция могла бы выглядеть примерно так:

myFunc(vector<string> s, int totalWordLength) {
    // Loop over strings in vector.
}

Я мог бы сделать что-то вроде этого, чтобы создать вектор строк.

const char *args[] = {"12345", "678"};
vector<string> s(args, end(args));

Но как мне тогда узнать размер строк (8) в этом, не проходя через него, так что я могу отправить его на myFunc(s, sizeOfStrings)?

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

Ответы [ 3 ]

1 голос
/ 31 марта 2020

Итерация по контейнеру (класс контейнера не имеет значения)

const char *args[] = {"12345", "678"};
vector<string> s(args, end(args));

size_t sizOfS = 0;
for( auto& item : s )
  sizOfS += item.length();

Другой способ объединяет процесс заполнения массива и вычисления длины:

const char *args[] = {"12345", "678"};
std::vector<std::string> s;
s.reserve(sizeof(args)/sizeof(args[0]));

size_t sizOfS = 0;
for( const std::string& item : args )
{
  sizOfS += item.length();
  s.push_back(item);
}

Независимо от того, что вы делаете, стоимость процесса будет O (n), где n = strings * their-total-length. Нет другого определенного способа, кроме нескольких функций, которые могут превратить l oop в одну строку. Даже если вы определите свой собственный контейнер, который будет отслеживать длину строк, его стоимость будет иметь тот же порядок.

Какой контейнер использовать, зависит от того, какие действия вы ожидаете выполнить, вектор получил постоянную стоимость случайного доступа к контейнеру предметов, но линейно увеличиваются затраты на его хранение. список может иметь дешевую вставку \ pu sh стоимость, но он получил последовательный итератор.

0 голосов
/ 31 марта 2020

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

Одно решение, использующее шаблон * variadi c, может быть оберткой, подобной этой ( live ):

#include <iostream>
#include <vector>
#include <string>

struct V
{
    template <typename ... T>
    V( T&& ... t ) : v{ std::forward<T>(t)... }
    {
        for ( const auto& s : v ) size += s.size();
    }

    std::vector<std::string> v;
    std::size_t size {0};
};

int main()
{
    const char *args[] = { "12345678", "6789", "1234", "5678" };

    V obj ( std::begin(args), std::end(args) );

    std::cout << "No. of Strings : " << obj.v.size() << '\n';
    std::cout << "Total Length   : " << obj.size << '\n';

    return 0;
}

Вывод:

No. of Strings : 4
Total Length   : 20
0 голосов
/ 31 марта 2020

Если вы хотите узнать длину всех строк в векторе и часто запрашивать их (это не одноразовая вещь), тогда вы можете вычислить длину строк, когда они добавлены вместе, и сохранить их с помощью вектор.

Быстрый пример этого с классом:

class MyClassFoo {
public:
  std::vector<std::string> items;
  std::size_t total_item_sizes = 0;

  void addItem(const std::string& item) {
    total_item_sizes += item.length(); // Add its length to the total
    items.emplace_back(item); // Add the item to the vector 
  }
}

Затем вы можете передать этот объект и запросить его.

Если вы хотите повысить эффективность, передайте по ссылке или измените параметры одноразового использования. Это важно с чем-то вроде std::vector, так как вы, вероятно, не хотите копировать все его элементы.

Кроме того, маловероятно, что это на самом деле необходимо, если вы не пытаетесь чтобы очень часто суммировать длины всех строк, а их много, ваше узкое место не будет повторяться по std::vector. Ваш спрос на «эффективность» пахнет преждевременной оптимизацией. Помните правило 20-80 (80% времени выполнения вашей программы тратится на выполнение 20% кода).

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