C++;-如何提取字符串中的有效字符串? 强>问题:我试图用C++从游戏名中提取一个有效的游戏模式,遗迹保卫战。
详细信息:C++;-如何提取字符串中的有效字符串? 强>问题:我试图用C++从游戏名中提取一个有效的游戏模式,遗迹保卫战。,c++,string,parsing,extraction,C++,String,Parsing,Extraction,详细信息: #include <cstdarg> #include <algorithm> #include <iostream> #include <string> #include <sstream> #include <map> #include <vector> std::map<std::string, std::vector<std::string> > ModeCompat
#include <cstdarg>
#include <algorithm>
#include <iostream>
#include <string>
#include <sstream>
#include <map>
#include <vector>
std::map<std::string, std::vector<std::string> > ModeCompatibilityMap;
static const unsigned int PrimaryModesCount = 11;
static char *PrimaryModes[] = {
"ap", "ar", "tr", "mr", "lm", "rd", "vr", "el", "sd", "cm", "cd"
};
static const unsigned int SecondaryModesCounts = 19;
static char *SecondaryModes[] = {
"dm", "rv", "mm", "du", "sh", "aa", "ai", "as", "id", "em", "np",
"sc", "om", "nt", "nm", "nb", "ro", "mo", "sp"
};
static const unsigned int MiscModesCount = 8;
static char *MiscModes[] = {
"ns", "nr", "ts", "pm", "oi", "mi", "fr", "so"
};
std::vector<std::string> Vectorize( int count, ... ) {
std::vector<std::string> result;
va_list vl;
va_start( vl, count );
for ( int i = 0; i < count; ++i ) {
char *buffer = va_arg( vl, char * );
result.push_back( buffer );
}
va_end( vl );
return result;
}
void InitializeModeCompatibilityMap() {
// Primary
ModeCompatibilityMap["ar"] = Vectorize( 1, "rv" );
ModeCompatibilityMap["tr"] = Vectorize( 2, "dm", "rv" );
ModeCompatibilityMap["mr"] = Vectorize( 8, "dm", "rv", "sh", "aa", "ai", "as", "ro", "mo" );
ModeCompatibilityMap["lm"] = Vectorize( 18, "dm", "rv", "mm", "du", "sh", "aa", "ai", "as", "id", "em", "np", "sc", "om", "nt", "nm", "nb", "ro", "mo" );
ModeCompatibilityMap["rd"] = Vectorize( 9, "dm", "rv", "mm", "sh", "aa", "ai", "as", "ro", "mo" );
ModeCompatibilityMap["vr"] = Vectorize( 9, "dm", "rv", "mm", "sh", "aa", "ai", "as", "ro", "mo" );
ModeCompatibilityMap["el"] = Vectorize( 18, "dm", "rv", "mm", "du", "sh", "aa", "ai", "as", "id", "em", "np", "sc", "om", "nt", "nm", "nb", "ro", "mo" );
ModeCompatibilityMap["sd"] = Vectorize( 9, "dm", "rv", "mm", "sh", "aa", "ai", "as", "ro", "mo" );
ModeCompatibilityMap["cm"] = Vectorize( 19, "dm", "rv", "mm", "du", "sh", "aa", "ai", "as", "id", "em", "np", "sc", "om", "nt", "nm", "nb", "ro", "mo", "sp" );
ModeCompatibilityMap["cd"] = Vectorize( 9, "dm", "rv", "mm", "sh", "aa", "ai", "as", "ro", "mo" );
// Secondary
ModeCompatibilityMap["dm"] = Vectorize( 8, "rv", "mm", "sh", "aa", "ai", "as", "ro", "mo" );
ModeCompatibilityMap["rv"] = Vectorize( 2, "dm", "sh" );
ModeCompatibilityMap["mm"] = Vectorize( 2, "dm", "sh" );
ModeCompatibilityMap["sh"] = Vectorize( 3, "dm", "rv", "mm" );
ModeCompatibilityMap["aa"] = Vectorize( 3, "dm", "ai", "as" );
ModeCompatibilityMap["ai"] = Vectorize( 3, "dm", "aa", "as" );
ModeCompatibilityMap["as"] = Vectorize( 3, "dm", "aa", "ai" );
ModeCompatibilityMap["ro"] = Vectorize( 2, "dm", "mo" );
ModeCompatibilityMap["mo"] = Vectorize( 2, "dm", "ro" );
}
std::vector<std::string> Tokenize( const std::string &string ) {
std::vector<std::string> tokens;
std::string token;
std::stringstream ss( string );
while ( ss >> token ) {
tokens.push_back( token );
}
return tokens;
}
void SanitizeString( std::string &in ) {
std::transform( in.begin(), in.end(), in.begin(), tolower );
for ( size_t i = 0; i < in.size(); ++i ) {
if ( in[i] < 'a' || in[i] > 'z' ) {
in.erase( i--, 1 );
}
}
}
std::vector<std::string> SplitString( const std::string &in, int count ) {
std::vector<std::string> result;
if ( in.length() % count != 0 ) {
return result;
}
for ( std::string::const_iterator i = in.begin(); i != in.end(); i += count ) {
result.push_back( std::string( i, i + count ) );
}
return result;
}
bool IsPrimaryGameMode( const std::string &in ) {
for ( int i = 0; i < PrimaryModesCount; ++i ) {
if ( strcmp( PrimaryModes[i], in.c_str() ) == 0 ) {
return true;
}
}
return false;
}
bool IsSecondaryGameMode( const std::string &in ) {
for ( int i = 0; i < SecondaryModesCounts; ++i ) {
if ( strcmp( SecondaryModes[i], in.c_str() ) == 0 ) {
return true;
}
}
return false;
}
bool IsMiscGameMode( const std::string &in ) {
for ( int i = 0; i < MiscModesCount; ++i ) {
if ( strcmp( MiscModes[i], in.c_str() ) == 0 ) {
return true;
}
}
return false;
}
bool IsValidGameMode( std::string in, std::string &out ) {
// 1. Strip all non-letters from the string and convert it to lower-case
SanitizeString( in );
// 2. Confirm that it is a multiple of 2
if ( in.length() == 0 || in.length() % 2 != 0 ) {
return false;
}
// 3. Split the string further into strings of 2 characters
std::vector<std::string> modes = SplitString( in, 2 );
// 4. Verify that each game mode is a valid game mode and is compatible with the others
bool primaryModeSet = false;
for ( size_t i = 0; i < modes.size(); ++i ) {
if ( IsPrimaryGameMode( modes[i] ) || IsSecondaryGameMode( modes[i] ) ) {
if ( IsPrimaryGameMode( modes[i] ) ) {
if ( primaryModeSet ) {
return false;
}
primaryModeSet = true;
}
if ( ModeCompatibilityMap.count( modes[i] ) > 0 ) {
std::vector<std::string> badModes = ModeCompatibilityMap[modes[i]];
for ( size_t j = 0; j < badModes.size(); ++j ) {
for ( size_t k = 0; k < modes.size(); ++k ) {
if ( badModes[j] == modes[k] ) {
return false;
}
}
}
}
} else if ( !IsMiscGameMode( modes[i] ) ) {
return false;
}
}
// 5. Assign the output variable with the game mode and return true
out = in;
return true;
}
std::string ExtractGameMode( const std::string &gameName ) {
std::vector<std::string> tokens = Tokenize( gameName );
std::string gameMode;
for ( size_t i = 0; i < tokens.size(); ++i ) {
if ( IsValidGameMode( tokens[i], gameMode ) ) {
return gameMode;
}
}
return "";
}
int main( int argc, char *argv[] ) {
InitializeModeCompatibilityMap();
std::string gameName = "DotA v6.60 -RDEM USA/CA LC";
std::string gameMode = ExtractGameMode( gameName );
std::cout << "Name: " << gameName << std::endl;
std::cout << "Mode: " << gameMode << std::endl;
return 0;
}
- 游戏名称最多可包含31个字符
- 有三种游戏模式类别:主要、次要和杂项
- 只能选择1个主要游戏模式
- 某些主要游戏模式与某些次要游戏模式不兼容
- 某些辅助游戏模式与其他辅助游戏模式不兼容
- 其他游戏模式可与所有其他游戏模式组合
结果:
#include <cstdarg>
#include <algorithm>
#include <iostream>
#include <string>
#include <sstream>
#include <map>
#include <vector>
std::map<std::string, std::vector<std::string> > ModeCompatibilityMap;
static const unsigned int PrimaryModesCount = 11;
static char *PrimaryModes[] = {
"ap", "ar", "tr", "mr", "lm", "rd", "vr", "el", "sd", "cm", "cd"
};
static const unsigned int SecondaryModesCounts = 19;
static char *SecondaryModes[] = {
"dm", "rv", "mm", "du", "sh", "aa", "ai", "as", "id", "em", "np",
"sc", "om", "nt", "nm", "nb", "ro", "mo", "sp"
};
static const unsigned int MiscModesCount = 8;
static char *MiscModes[] = {
"ns", "nr", "ts", "pm", "oi", "mi", "fr", "so"
};
std::vector<std::string> Vectorize( int count, ... ) {
std::vector<std::string> result;
va_list vl;
va_start( vl, count );
for ( int i = 0; i < count; ++i ) {
char *buffer = va_arg( vl, char * );
result.push_back( buffer );
}
va_end( vl );
return result;
}
void InitializeModeCompatibilityMap() {
// Primary
ModeCompatibilityMap["ar"] = Vectorize( 1, "rv" );
ModeCompatibilityMap["tr"] = Vectorize( 2, "dm", "rv" );
ModeCompatibilityMap["mr"] = Vectorize( 8, "dm", "rv", "sh", "aa", "ai", "as", "ro", "mo" );
ModeCompatibilityMap["lm"] = Vectorize( 18, "dm", "rv", "mm", "du", "sh", "aa", "ai", "as", "id", "em", "np", "sc", "om", "nt", "nm", "nb", "ro", "mo" );
ModeCompatibilityMap["rd"] = Vectorize( 9, "dm", "rv", "mm", "sh", "aa", "ai", "as", "ro", "mo" );
ModeCompatibilityMap["vr"] = Vectorize( 9, "dm", "rv", "mm", "sh", "aa", "ai", "as", "ro", "mo" );
ModeCompatibilityMap["el"] = Vectorize( 18, "dm", "rv", "mm", "du", "sh", "aa", "ai", "as", "id", "em", "np", "sc", "om", "nt", "nm", "nb", "ro", "mo" );
ModeCompatibilityMap["sd"] = Vectorize( 9, "dm", "rv", "mm", "sh", "aa", "ai", "as", "ro", "mo" );
ModeCompatibilityMap["cm"] = Vectorize( 19, "dm", "rv", "mm", "du", "sh", "aa", "ai", "as", "id", "em", "np", "sc", "om", "nt", "nm", "nb", "ro", "mo", "sp" );
ModeCompatibilityMap["cd"] = Vectorize( 9, "dm", "rv", "mm", "sh", "aa", "ai", "as", "ro", "mo" );
// Secondary
ModeCompatibilityMap["dm"] = Vectorize( 8, "rv", "mm", "sh", "aa", "ai", "as", "ro", "mo" );
ModeCompatibilityMap["rv"] = Vectorize( 2, "dm", "sh" );
ModeCompatibilityMap["mm"] = Vectorize( 2, "dm", "sh" );
ModeCompatibilityMap["sh"] = Vectorize( 3, "dm", "rv", "mm" );
ModeCompatibilityMap["aa"] = Vectorize( 3, "dm", "ai", "as" );
ModeCompatibilityMap["ai"] = Vectorize( 3, "dm", "aa", "as" );
ModeCompatibilityMap["as"] = Vectorize( 3, "dm", "aa", "ai" );
ModeCompatibilityMap["ro"] = Vectorize( 2, "dm", "mo" );
ModeCompatibilityMap["mo"] = Vectorize( 2, "dm", "ro" );
}
std::vector<std::string> Tokenize( const std::string &string ) {
std::vector<std::string> tokens;
std::string token;
std::stringstream ss( string );
while ( ss >> token ) {
tokens.push_back( token );
}
return tokens;
}
void SanitizeString( std::string &in ) {
std::transform( in.begin(), in.end(), in.begin(), tolower );
for ( size_t i = 0; i < in.size(); ++i ) {
if ( in[i] < 'a' || in[i] > 'z' ) {
in.erase( i--, 1 );
}
}
}
std::vector<std::string> SplitString( const std::string &in, int count ) {
std::vector<std::string> result;
if ( in.length() % count != 0 ) {
return result;
}
for ( std::string::const_iterator i = in.begin(); i != in.end(); i += count ) {
result.push_back( std::string( i, i + count ) );
}
return result;
}
bool IsPrimaryGameMode( const std::string &in ) {
for ( int i = 0; i < PrimaryModesCount; ++i ) {
if ( strcmp( PrimaryModes[i], in.c_str() ) == 0 ) {
return true;
}
}
return false;
}
bool IsSecondaryGameMode( const std::string &in ) {
for ( int i = 0; i < SecondaryModesCounts; ++i ) {
if ( strcmp( SecondaryModes[i], in.c_str() ) == 0 ) {
return true;
}
}
return false;
}
bool IsMiscGameMode( const std::string &in ) {
for ( int i = 0; i < MiscModesCount; ++i ) {
if ( strcmp( MiscModes[i], in.c_str() ) == 0 ) {
return true;
}
}
return false;
}
bool IsValidGameMode( std::string in, std::string &out ) {
// 1. Strip all non-letters from the string and convert it to lower-case
SanitizeString( in );
// 2. Confirm that it is a multiple of 2
if ( in.length() == 0 || in.length() % 2 != 0 ) {
return false;
}
// 3. Split the string further into strings of 2 characters
std::vector<std::string> modes = SplitString( in, 2 );
// 4. Verify that each game mode is a valid game mode and is compatible with the others
bool primaryModeSet = false;
for ( size_t i = 0; i < modes.size(); ++i ) {
if ( IsPrimaryGameMode( modes[i] ) || IsSecondaryGameMode( modes[i] ) ) {
if ( IsPrimaryGameMode( modes[i] ) ) {
if ( primaryModeSet ) {
return false;
}
primaryModeSet = true;
}
if ( ModeCompatibilityMap.count( modes[i] ) > 0 ) {
std::vector<std::string> badModes = ModeCompatibilityMap[modes[i]];
for ( size_t j = 0; j < badModes.size(); ++j ) {
for ( size_t k = 0; k < modes.size(); ++k ) {
if ( badModes[j] == modes[k] ) {
return false;
}
}
}
}
} else if ( !IsMiscGameMode( modes[i] ) ) {
return false;
}
}
// 5. Assign the output variable with the game mode and return true
out = in;
return true;
}
std::string ExtractGameMode( const std::string &gameName ) {
std::vector<std::string> tokens = Tokenize( gameName );
std::string gameMode;
for ( size_t i = 0; i < tokens.size(); ++i ) {
if ( IsValidGameMode( tokens[i], gameMode ) ) {
return gameMode;
}
}
return "";
}
int main( int argc, char *argv[] ) {
InitializeModeCompatibilityMap();
std::string gameName = "DotA v6.60 -RDEM USA/CA LC";
std::string gameMode = ExtractGameMode( gameName );
std::cout << "Name: " << gameName << std::endl;
std::cout << "Mode: " << gameMode << std::endl;
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
映射模式兼容性映射;
静态常数unsigned int primarymodescont=11;
静态字符*主模式[]={
“ap”、“ar”、“tr”、“mr”、“lm”、“rd”、“vr”、“el”、“sd”、“cm”、“cd”
};
静态常量unsigned int secondary modesconts=19;
静态字符*二次模式[]={
“dm”、“rv”、“mm”、“du”、“sh”、“aa”、“ai”、“as”、“id”、“em”、“np”,
“sc”、“om”、“nt”、“nm”、“nb”、“ro”、“mo”、“sp”
};
静态常量unsigned int miscmodescont=8;
静态字符*MiscModes[]={
“ns”、“nr”、“ts”、“pm”、“oi”、“mi”、“fr”、“so”
};
向量向量化(整数计数,…){
std::向量结果;
va_列表vl;
va_启动(vl,计数);
对于(int i=0;i>令牌){
代币。推回(代币);
}
归还代币;
}
void SanitizeString(标准::字符串和输入){
std::transform(in.begin()、in.end()、in.begin()、tolower);
对于(大小i=0;i'z'中){
in.擦除(i--,1);
}
}
}
std::vector SplitString(常量std::string&in,int count){
std::向量结果;
如果(in.length()%count!=0){
返回结果;
}
for(std::string::const_迭代器i=in.begin();i!=in.end();i+=count){
result.push_back(std::string(i,i+count));
}
返回结果;
}
bool isprimary游戏模式(const std::string&in){
对于(int i=0;i bool IsSecondaryValidWithPrimary(unsigned int primaryIndex, unsigned int secondaryIndex)
{
static bool secondaryValidWithPrimary[numPrimaryModes][numSecondaryModes] = {...}
if (primaryIndex < numPrimaryModes && secondaryIndex < numSecondaryModes)
{
return secondaryValidWithPrimary[primaryIndex][secondaryIndex]
}
else
{
//... this should never happen, throw your favorite exception
}
}
map<const char*, bool> mapSecondaryCompatibility;
struct tGameType
{
char szName[3];
mapSecondaryCompatibility m_compat;
}