获取长度字符串的范围百分比
Get range percentage of a length string
我遇到了问题。我正在学习 C++。我采用了扑克环境;
目标是从字符串长度中得到一定的手牌范围;该字符串代表扑克游戏中的所有起手牌,顺序为强手。
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";
弦手的长度为662;为了获得范围,我们需要排除一定比例的起始手牌并排除一定比例的结束手牌。
因此,如果我需要最后 10% 的牌,我将排除前 90% 的牌。
如果我需要 30% 到 60% 之间,我将排除前 29% 和后 39% 。
这很难,因为字符串不能在任何地方剪切,一个好的输出应该是例如 72o,J5o,63s,92s,73s,Q2o,J4o,83s,
有或没有逗号到最后,这不是最重要的。
我试图创建一个这样的子字符串:
int startpos = 0;
int stoppos= (662 * 7) / 100;
string str2 = hand.substr(startpos, stoppos);
cout << str2 << endl;
但这不是范围问题的答案。它只得到第一个 X%,而且切割不好,输出是:AA,KK,QQ,JJ,A
应该是:AA,KK,QQ,JJ,AKs
我为此花了很多时间。我乐于寻求建议、指导,甚至是解决方案 ..
此致,
贵
这是一种方法:获取您的字符串,将其转换为序列,丢弃您不感兴趣的序列部分,然后将其转换回字符串。
下面是我在 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)
在两个 Whosebug 线程 here and here 的帮助下,我将 Python 代码翻译成(诚然不是惯用的)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;
}
另一种方法:找到我们感兴趣的子字符串的索引,并提取该子字符串。不过也没有短多少。
#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;
}
我只是想指出,弦的百分比与手的百分比不同。
不同的手或多或少比其他人更常见。具体来说,非同花牌(例如 AKo)出现的可能性是同花版本 (AK) 的三倍,而对子的可能性是非同花牌的一半。这是因为从一副牌中抽出牌的组合学。
对于配对,每个等级有 C(4,2) = 6 种可能的组合。
对于同花牌,只有花色不同,所以有 4 种可能的组合。
对于非同花牌,第一张牌有四种可能的花色,但第二张牌只有三种花色(否则就是同花),所以有 12 种组合。
为了获得正确的百分比,根据发牌的可能性,您需要相应地加权。
我遇到了问题。我正在学习 C++。我采用了扑克环境; 目标是从字符串长度中得到一定的手牌范围;该字符串代表扑克游戏中的所有起手牌,顺序为强手。
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";
弦手的长度为662;为了获得范围,我们需要排除一定比例的起始手牌并排除一定比例的结束手牌。
因此,如果我需要最后 10% 的牌,我将排除前 90% 的牌。 如果我需要 30% 到 60% 之间,我将排除前 29% 和后 39% 。
这很难,因为字符串不能在任何地方剪切,一个好的输出应该是例如 72o,J5o,63s,92s,73s,Q2o,J4o,83s,
有或没有逗号到最后,这不是最重要的。
我试图创建一个这样的子字符串:
int startpos = 0;
int stoppos= (662 * 7) / 100;
string str2 = hand.substr(startpos, stoppos);
cout << str2 << endl;
但这不是范围问题的答案。它只得到第一个 X%,而且切割不好,输出是:AA,KK,QQ,JJ,A
应该是:AA,KK,QQ,JJ,AKs
我为此花了很多时间。我乐于寻求建议、指导,甚至是解决方案 ..
此致, 贵
这是一种方法:获取您的字符串,将其转换为序列,丢弃您不感兴趣的序列部分,然后将其转换回字符串。
下面是我在 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)
在两个 Whosebug 线程 here and here 的帮助下,我将 Python 代码翻译成(诚然不是惯用的)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;
}
另一种方法:找到我们感兴趣的子字符串的索引,并提取该子字符串。不过也没有短多少。
#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;
}
我只是想指出,弦的百分比与手的百分比不同。
不同的手或多或少比其他人更常见。具体来说,非同花牌(例如 AKo)出现的可能性是同花版本 (AK) 的三倍,而对子的可能性是非同花牌的一半。这是因为从一副牌中抽出牌的组合学。
对于配对,每个等级有 C(4,2) = 6 种可能的组合。
对于同花牌,只有花色不同,所以有 4 种可能的组合。
对于非同花牌,第一张牌有四种可能的花色,但第二张牌只有三种花色(否则就是同花),所以有 12 种组合。
为了获得正确的百分比,根据发牌的可能性,您需要相应地加权。