0

Take string input from user and than put it in a vector(first) in c++ for example if string is"038493" and when I access first[0] it will give me 0. How can we do it faster.

    string p;
    cin>>p;

    for(i=0;i<n;i++){
    first.push_back(p[i]);
    }

I used this but this is slow, tell me good method to do it.

Barry
  • 286,269
  • 29
  • 621
  • 977
Tushar Gupta
  • 1,603
  • 13
  • 20
  • `vector first(p.begin(), p.end());` – juanchopanza Jan 02 '15 at 20:42
  • 5
    Unless your string is very large, this is unlikely to be the bottleneck. What are you trying to do? Why do you think it is slow? @juanchopanza's method requires `1` heap allocation while yours will need `O(log p.size())` allocations. Is the size of `p` large enough to maek a difference? – Pradhan Jan 02 '15 at 20:44
  • Possibly relevant - ["Using scanf() in C++ programs is faster than using cin?"](http://stackoverflow.com/questions/1042110/using-scanf-in-c-programs-is-faster-than-using-cin). – Pradhan Jan 02 '15 at 20:49
  • @self When the size of a vector becomes equal of a `vector` to its capacity, the capacity gets scaled by some implementation defined constant. `gcc` uses `2`, although there are better choices of this constant. While I don't have a standard reference, see the "Memory Handling" section [here](https://github.com/facebook/folly/blob/master/folly/docs/FBVector.md). – Pradhan Jan 02 '15 at 20:58
  • 2
    WTF at editting to be an *entirely different question*. Was really confusing trying to understand the answers/comments. Reverting. – Barry Jan 02 '15 at 20:59
  • You don't need a `vector`, you can index your string the same way – w.b Jan 02 '15 at 20:59

3 Answers3

1
first.insert(first.end(), p.begin(), p.begin() + n);

if n is actually the length of the whole string, it'd be better to use:

first.insert(first.end(), p.begin(), p.end());
Brian Rodriguez
  • 487
  • 3
  • 10
0

//`for(char& c : p) { // first.push_back(c); //}

Apologies, I was mistaken. I think if you use this constructor for the vector it would be the fastest way. Juan has the right idea.

std::vector<char> first(p.begin(), p.end());
  • 1
    You might want to explain a little bit of the theory behind your answer. –  Jan 02 '15 at 20:47
0

Fastest: do nothing. std::string can basically function as std::vector<char> for most purposes, and doing literally nothing is always going to be faster than doing something.

std::string p;
cin >> p;

// just use p
// p[0] is the first char, e.g. '0', so you don't have to do anything
// p[1] is the second, etc. 
// p.size() is the size

Next fastest: just directly construct your vector:

std::vector<char> data(p.begin(), p.end());

That will make sure to do only one allocation of the correct amount (of at least p.size()), and will copy the string into the vector as efficiently as feasible.

Next: add each character one at a time:

// C++11
std::vector<char> data;
for (char c : p) {
    data.push_back(c);
}

// C++03
for (size_t i = 0; i < data.size(); ++i) {
    data.push_back(p[i]);
}

The longer the string, the more extra allocations/copies will be done as opposed to the direct-construction method. The exact amount is implementation dependent, but this approach will always be slower - even your particular implementation default-constructs a vector with large initial capacity (since you would at least have to branch on each push_back to check if you had to resize... whereas the direct construction wouldn't even have to do that).

Barry
  • 286,269
  • 29
  • 621
  • 977