Get percentage of string length

I have a problem. I am learning C ++. I took the poker context; The goal is to get a certain range of hands from the length of the line ; the line represents all starting hands in the poker game, in order of the strongest first.

 string hand = "AA,KK,QQ,JJ,AKs,AKo,AQs,AQo,TT,AJs,ATs,AJo,KQs,KJs,KTs,QJs,ATo,QTs,JTs,A9s,A9o,KQo,A8s,A8o,A7s,A7o,A6s,A6o,A5s,A5o,A4s,99,A4o,A3s,A2s,KJo,J9s,T9s,Q9s,QJo,KTo,Q9o,88,77,66,QTo,A3o,A2o,JTo,K9s,K8s,K7s,K6s,K5s,K4s,K3s,K2s,Q8s,Q7s,Q6s,Q5s,K9o,J8s,T8s,98s,97s,87s,86s,76s,96s,75s,65s,64s,J9o,T9o,55,54s,53s,52s,K8o,43s,32s,42s,J7s,T7s,K7o,44,33,22,Q4s,Q3s,Q2s,J6s,J5s,T6s,T5s,J4s,K6o,Q8o,J8o,T8o,98o,97o,87o,85s,K5o,K4o,K3o,K2o,95s,74s,76o,65o,54o,84s,94s,Q7o,J7o,T7o,Q6o,J3s,T4s,J2s,Q5o,T3s,T2s,Q4o,J6o,86o,T6o,96o,93s,Q3o,74o,84o,75o,64o,T2o,94o,53o,93o,63o,43o,92o,73o,83o,52o,82o,42o,62o,72o,J5o,63s,92s,73s,Q2o,J4o,83s,85o,82s,T5o,95o,J3o,62s,T4o,J2o,72s,T3o,32o";

      

The line length of the string is 662 ; To get the range, we need to exclude the percentage of the starting hand and exclude the percentage of the ending hand.

So, if I want the last 10% of hands, I'll exclude the first 90%. if I need 30% to 60%, I will exclude the first 29% and the last 39%.

It is difficult, because the string cannot be cut anywhere, a good result should be, for example, 72o,J5o,63s,92s,73s,Q2o,J4o,83s,

with or without a comma, this is not the most important thing.

I tried to create a substring like this:

  int startpos = 0;
  int stoppos= (662 * 7) / 100;
  string str2 = hand.substr(startpos, stoppos);
  cout <<  str2 << endl;

      

But this is not the answer to the range problem. It only gets the first X% and the cut is bad, the output is: AA,KK,QQ,JJ,A

and should be:AA,KK,QQ,JJ,AKs

I've spent many hours on this. I am open to advice, directions and even a solution.

Best regards, GUI

+3


source to share


3 answers


Here's one way to do it: take your string, convert it to a sequence, discard parts of the sequence you're not interested in, then convert it to a string.

So, how would I do it in Python:

start, stop = 30, 60
hands = 'AA,KK,QQ,JJ,AKs,AKo,AQs,AQo,TT,AJs,ATs,AJo,KQs,KJs,KTs,QJs,\
ATo,QTs,JTs,A9s,A9o,KQo,A8s,A8o,A7s,A7o,A6s,A6o,A5s,A5o,A4s,99,A4o,A3s,A2s,\
KJo,J9s,T9s,Q9s,QJo,KTo,Q9o,88,77,66,QTo,A3o,A2o,JTo,K9s,K8s,K7s,K6s,K5s,K4s,\
K3s,K2s,Q8s,Q7s,Q6s,Q5s,K9o,J8s,T8s,98s,97s,87s,86s,76s,96s,75s,65s,64s,J9o,\
T9o,55,54s,53s,52s,K8o,43s,32s,42s,J7s,T7s,K7o,44,33,22,Q4s,Q3s,Q2s,J6s,J5s,\
T6s,T5s,J4s,K6o,Q8o,J8o,T8o,98o,97o,87o,85s,K5o,K4o,K3o,K2o,95s,74s,76o,65o,\
54o,84s,94s,Q7o,J7o,T7o,Q6o,J3s,T4s,J2s,Q5o,T3s,T2s,Q4o,J6o,86o,T6o,96o,93s,\
Q3o,74o,84o,75o,64o,T2o,94o,53o,93o,63o,43o,92o,73o,83o,52o,82o,42o,62o,72o,\
J5o,63s,92s,73s,Q2o,J4o,83s,85o,82s,T5o,95o,J3o,62s,T4o,J2o,72s,T3o,32o'

hands = hands.split(',')
hands = hands[start * len(hands) / 100 : stop * len(hands) / 100]
print ','.join(hands)

      



With the help of two Stackoverflow threads here and here , I have translated the Python code (admittedly not idiomatic) C ++:

#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

vector<string> &split(const string &s, char delim, vector<string> &elems) {
  stringstream ss(s);
  string item;
  while (getline(ss, item, delim)) {
    elems.push_back(item);
  }
  return elems;
}

vector<string> split(const string &s, char delim) {
  vector<string> elems;
  split(s, delim, elems);
  return elems;
}

int main() {
  // percentage markers to keep, 30% -- 60% here
  int start = 30, stop = 60;
  string hands = "AA,KK,QQ,JJ,AKs,AKo,AQs,AQo,TT,AJs,ATs,AJo,KQs,KJs,KTs,QJs,\
ATo,QTs,JTs,A9s,A9o,KQo,A8s,A8o,A7s,A7o,A6s,A6o,A5s,A5o,A4s,99,A4o,A3s,A2s,\
KJo,J9s,T9s,Q9s,QJo,KTo,Q9o,88,77,66,QTo,A3o,A2o,JTo,K9s,K8s,K7s,K6s,K5s,K4s,\
K3s,K2s,Q8s,Q7s,Q6s,Q5s,K9o,J8s,T8s,98s,97s,87s,86s,76s,96s,75s,65s,64s,J9o,\
T9o,55,54s,53s,52s,K8o,43s,32s,42s,J7s,T7s,K7o,44,33,22,Q4s,Q3s,Q2s,J6s,J5s,\
T6s,T5s,J4s,K6o,Q8o,J8o,T8o,98o,97o,87o,85s,K5o,K4o,K3o,K2o,95s,74s,76o,65o,\
54o,84s,94s,Q7o,J7o,T7o,Q6o,J3s,T4s,J2s,Q5o,T3s,T2s,Q4o,J6o,86o,T6o,96o,93s,\
Q3o,74o,84o,75o,64o,T2o,94o,53o,93o,63o,43o,92o,73o,83o,52o,82o,42o,62o,72o,\
J5o,63s,92s,73s,Q2o,J4o,83s,85o,82s,T5o,95o,J3o,62s,T4o,J2o,72s,T3o,32o";

  vector<string> hands_ = split(hands, ',');
  start = start * hands_.size() / 100;
  stop = stop * hands_.size() / 100;

  stringstream buffer;
  for (size_t i = start; i < stop; ++i) {
    if(i != start)
      buffer << ',';
    buffer << hands_[i];
  }
  string output = buffer.str();

  cout << output << endl;
  return 0;
}

      

+4


source


Another approach is to find the indices of the substring we are interested in and extract that substring. Not much shorter, however.



#include <algorithm>
#include <iostream>
#include <string>

using namespace std;

int main() {
  // percentage markers to keep, 30% -- 60% here
  int start = 30, stop = 60;
  string hands = "AA,KK,QQ,JJ,AKs,AKo,AQs,AQo,TT,AJs,ATs,AJo,KQs,KJs,KTs,QJs,\
ATo,QTs,JTs,A9s,A9o,KQo,A8s,A8o,A7s,A7o,A6s,A6o,A5s,A5o,A4s,99,A4o,A3s,A2s,\
KJo,J9s,T9s,Q9s,QJo,KTo,Q9o,88,77,66,QTo,A3o,A2o,JTo,K9s,K8s,K7s,K6s,K5s,K4s,\
K3s,K2s,Q8s,Q7s,Q6s,Q5s,K9o,J8s,T8s,98s,97s,87s,86s,76s,96s,75s,65s,64s,J9o,\
T9o,55,54s,53s,52s,K8o,43s,32s,42s,J7s,T7s,K7o,44,33,22,Q4s,Q3s,Q2s,J6s,J5s,\
T6s,T5s,J4s,K6o,Q8o,J8o,T8o,98o,97o,87o,85s,K5o,K4o,K3o,K2o,95s,74s,76o,65o,\
54o,84s,94s,Q7o,J7o,T7o,Q6o,J3s,T4s,J2s,Q5o,T3s,T2s,Q4o,J6o,86o,T6o,96o,93s,\
Q3o,74o,84o,75o,64o,T2o,94o,53o,93o,63o,43o,92o,73o,83o,52o,82o,42o,62o,72o,\
J5o,63s,92s,73s,Q2o,J4o,83s,85o,82s,T5o,95o,J3o,62s,T4o,J2o,72s,T3o,32o";

  int nhands = count(hands.begin(), hands.end(), ',');
  start = start * nhands / 100;     // percentage -> comma count
  stop = stop * nhands / 100;       // percentage -> comma count

  int start_ = start, stop_ = stop; // copies
  int i = 0, substr_start, substr_end;

  for (i = 0; i < hands.length() && start_ > 0; ++i) {
    if (hands[i] == ',')
      start_--;
  }
  substr_start = i;

  stop_ -= start - 1;               // already counted 'start' commas
  for (; i < hands.length() && stop_ > 0; ++i) {
    if (hands[i] == ',')
      stop_--;
  }
  substr_end = i;

  cout << hands.substr(substr_start, substr_end - substr_start - 1) << endl;
  return 0;
}

      

+2


source


I just want to point out that the row percentage is different from the hand percentage.

Different hands are more or less common than others. In particular, Offsuit hands (like AKo) are three times more common than matching versions (AKs), and pairs are twice as common as offsuit hands. This is due to the combinatorics of drawing cards from the deck.

For pairs, there are C (4,2) = 6 possible combinations for each rank.

Only the suit changes for the matching hands, so 4 combinations are possible.

For RC hands, there are four possible options for the first card, but only three for the second (otherwise it would be convenient), so there are 12 combinations.

To get the correct percentage in terms of the likelihood of a deal, you need to raise your hands accordingly.

+1


source







All Articles