String 计算XYYX类型的回文数
以下是一个采访问题。我没有成功,因为我没有得到一个更好、更有效的答案String 计算XYYX类型的回文数,string,algorithm,optimization,String,Algorithm,Optimization,以下是一个采访问题。我没有成功,因为我没有得到一个更好、更有效的答案 给定一个字符串S,我们需要找到模式xyx的回文数,其中X和Y是来自同一字符串S的任意字符 注意:我们不能更改字符串S中字符的顺序。X和Y的值也可以相同,但它们在字符串S中的位置需要不同 另外,如果两个字符串在字符串S中的索引对于最终字符串中的任何字符都不同,则这两个字符串是不同的 示例:假设字符串是S=abbaab,那么答案是4 这四种回文是: abba [Indexes : 1,2,3,4] abba [Indexes
给定一个字符串S,我们需要找到模式xyx的回文数,其中X和Y是来自同一字符串S的任意字符 注意:我们不能更改字符串S中字符的顺序。X和Y的值也可以相同,但它们在字符串S中的位置需要不同 另外,如果两个字符串在字符串S中的索引对于最终字符串中的任何字符都不同,则这两个字符串是不同的 示例:假设字符串是S=abbaab,那么答案是4 这四种回文是:
abba [Indexes : 1,2,3,4]
abba [Indexes : 1,2,3,5]
baab [Indexes : 3,4,5,6]
baab [Indexes : 2,4,5,6]
那个么如何计算这些回文的数量呢。字符串的长度可以达到1000000。那么什么是最好的方法呢?正如在问题的讨论部分所发现的,目标不是找到“真正的”回文,而是像“xyx*”这样的东西,其中每个匹配的“X*”都被计数 这意味着您需要在迭代输入
S
时保持某种搜索状态,因为在S
的每个位置上,可能会出现多个回文
现在考虑“ABBAAA……”的输入(最坏情况)。(以ABBA开头,以<代码>(1000000—4)< /代码>‘a’-字符结束。在这种情况下我们需要维护多少个状态实例?答案取决于状态机(状态保持)的定义。< /P> 上面提到的状态机是匹配的检测器。让我们看看一些代码(F#selected):
类型PState
是一个有区别的联合体,它描述状态机的各个状态以及各个状态所需的数据
tryProgress
函数获取fsm的一个实例和来自S的下一个输入字符,并返回一个Pstate选项
结果。如果该字符未导致新的可能状态,则此函数返回None
,否则返回Some
最后同样重要的是,count
函数迭代输入字符串中的字符(也可以按字符读取输入文件…),并将tryProgress
函数应用于每个活动状态机。它还决定“忘记”哪些实例并决定何时增加伪回文的计数器
回到我们所谓的最坏情况输入场景,保留的FSM实例数量将随着字符数的增加而增加,因为情况X=Y也无助于减少要保留的状态数量。在序列结束之前,大多数实例将处于状态XN('a','a')
因此,我很想把这个问题归类为不适定问题。
(“aaaaaaa”->[0,1,2,3;0,1,2,4;0,1,2,5;0,1,2,6;1,2,3,4;1,2,3,5;1,2,3,6;…]
)
更新
作为代码示例的另一种语言,这里是最流行的C++版本:
#include <cstdint>
#include <string>
#include <list>
#include <iostream>
#include <exception>
#include <stdexcept>
enum class PStateName
{
X,Y0,Y1,X1,XN,END,FAIL
};
struct PState
{
PStateName state;
char x;
char y;
PState(PStateName s, char x0, char y0 = '\0')
: state(s)
, x(x0)
, y(y0)
{
}
static PState MakeX(char x0)
{
return PState(PStateName::X, x0);
}
static PState To_Y0(const PState &pre, char y0)
{
return PState(PStateName::Y0,pre.x, y0);
}
static PState To_Y1(const PState&pre)
{
return PState(PStateName::Y1,pre.x,pre.y);
}
static PState To_X1(const PState&pre)
{
return PState(PStateName::X1,pre.x,pre.y);
}
static PState To_XN(const PState&pre)
{
return PState(PStateName::XN,pre.x,pre.y);
}
static PState To_End(const PState&pre)
{
return PState(PStateName::END,pre.x,pre.y);
}
static PState To_Fail(const PState&pre)
{
return PState(PStateName::FAIL,pre.x,pre.y);
}
};
PState Progress(const PState& current, char c)
{
switch(current.state)
{
case PStateName::X:
return PState::To_Y0(current,c);
break;
case PStateName::Y0:
if(c == current.y)
return PState::To_Y1(current);
else
return PState::To_Fail(current);
break;
case PStateName::Y1:
if(c == current.x)
return PState::To_X1(current);
else
return PState::To_Fail(current);
break;
case PStateName::X1:
if(c == current.x)
return PState::To_XN(current);
else
return PState::To_End(current);
break;
case PStateName::XN:
if(c == current.x)
return PState::To_XN(current);
else
return PState::To_End(current);
break;
case PStateName::END:
throw std::exception(/*"Instances in state End should have been dismissed and never show here."*/);
break;
case PStateName::FAIL:
throw std::exception(/*"Instances in state FAIL should have been dismissed and never show here."*/);
break;
default:
throw std::exception(/*"Fix me! Unknown state in a switch statement!"*/);
break;
}
}
typedef std::list<PState> StateList;
StateList nextChar( const StateList& actives, char c, size_t &counter )
{
StateList result;
for(auto fsm : actives)
{
PState fsm1 = Progress(fsm,c);
switch(fsm1.state)
{
case PStateName::FAIL: // Do nothing - weed out and do not count it.
break;
case PStateName::X1:
counter++;
result.push_back(fsm1);
break;
case PStateName::XN:
counter++;
result.push_back(fsm1);
break;
case PStateName::END:
counter++;
break;
default:
result.push_back(fsm1);
break;
}
}
result.push_back(PState::MakeX(c));
return result;
}
size_t countString( const std::string& s)
{
size_t counter = 0;
StateList current;
for(auto c : s)
{
current = nextChar(current,c,counter);
}
return counter;
}
size_t countFile( const std::string& filePath)
{
size_t counter = 0;
StateList current;
// TODO: read file char by char and feed it to nextChar as shown in the countString() function.
return counter;
}
int main(int argc, const char * argv[])
{
std::string s("abbaab");
std::cout <<"\"" << s << "\": " << countString(s) << std::endl;
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
枚举类PStateName
{
十、 Y0,Y1,X1,XN,结束,失败
};
结构PState
{
PStateName状态;
字符x;
chary;
PState(PStateName s,char x0,char y0='\0')
:州
,x(x0)
,y(y0)
{
}
静态PState MakeX(字符x0)
{
返回PState(PStateName::X,x0);
}
静态PState To_Y0(常量PState&前置,字符Y0)
{
返回PState(PStateName::Y0,pre.x,Y0);
}
静态PState到_Y1(常量PState和pre)
{
返回PState(PStateName::Y1,pre.x,pre.y);
}
静态PState到_X1(常量PState和pre)
{
返回PState(PStateName::X1,pre.x,pre.y);
}
静态PState到_XN(常数PState和pre)
{
返回PState(PStateName::XN,pre.x,pre.y);
}
静态PState至_端(const PState&pre)
{
返回PState(PStateName::END,pre.x,pre.y);
}
静态PState To_Fail(const-PState和pre)
{
返回PState(PStateName::FAIL,pre.x,pre.y);
}
};
p状态进度(常数p状态和当前值,字符c)
{
开关(当前状态)
{
案例PStateName::X:
返回PState::到_Y0(当前,c);
打破
案例PStateName::Y0:
如果(c==current.y)
返回PState::至_Y1(当前);
其他的
返回PState::To_Fail(当前);
打破
案例PStateName::Y1:
如果(c==current.x)
返回PState::至_X1(当前);
其他的
返回PState::To_Fail(当前);
打破
案例PStateName::X1:
如果(c==current.x)
返回PState::到XN(当前);
其他的
返回PState::至_端(当前);
打破
案例PStateName::XN:
如果(c==current.x)
返回PState::到XN(当前);
其他的
返回PState::至_端(当前);
打破
案例PStateName::结束:
throw std::exception(/*“状态结束中的实例应该被忽略,并且永远不会显示在这里。”*/);
打破
案例PStateName::失败:
throw std::exception(/*“状态为FAIL的实例应该被忽略,并且永远不会在此处显示。”*/);
打破
违约:
抛出std::exception(/*“修复我!switch语句中的未知状态!”*/);
打破
}
}
typedef std::list StateList;
statelistnextchar(常量StateList和actives、字符c、大小和计数器)
{
国家名单结果;
用于(自动fsm:actives)
{
PState fsm1=进度(fsm,c);
开关(fsm1.状态)
{
case PStateName::FAIL://什么都不做-剔除并不计算它。
打破
案例PStateName::X1:
计数器++;
结果:推回(fsm1);
打破
案例PStateName::XN:
计数器++;
结果:推回(fsm1);
布雷亚
#include <cstdint>
#include <string>
#include <list>
#include <iostream>
#include <exception>
#include <stdexcept>
enum class PStateName
{
X,Y0,Y1,X1,XN,END,FAIL
};
struct PState
{
PStateName state;
char x;
char y;
PState(PStateName s, char x0, char y0 = '\0')
: state(s)
, x(x0)
, y(y0)
{
}
static PState MakeX(char x0)
{
return PState(PStateName::X, x0);
}
static PState To_Y0(const PState &pre, char y0)
{
return PState(PStateName::Y0,pre.x, y0);
}
static PState To_Y1(const PState&pre)
{
return PState(PStateName::Y1,pre.x,pre.y);
}
static PState To_X1(const PState&pre)
{
return PState(PStateName::X1,pre.x,pre.y);
}
static PState To_XN(const PState&pre)
{
return PState(PStateName::XN,pre.x,pre.y);
}
static PState To_End(const PState&pre)
{
return PState(PStateName::END,pre.x,pre.y);
}
static PState To_Fail(const PState&pre)
{
return PState(PStateName::FAIL,pre.x,pre.y);
}
};
PState Progress(const PState& current, char c)
{
switch(current.state)
{
case PStateName::X:
return PState::To_Y0(current,c);
break;
case PStateName::Y0:
if(c == current.y)
return PState::To_Y1(current);
else
return PState::To_Fail(current);
break;
case PStateName::Y1:
if(c == current.x)
return PState::To_X1(current);
else
return PState::To_Fail(current);
break;
case PStateName::X1:
if(c == current.x)
return PState::To_XN(current);
else
return PState::To_End(current);
break;
case PStateName::XN:
if(c == current.x)
return PState::To_XN(current);
else
return PState::To_End(current);
break;
case PStateName::END:
throw std::exception(/*"Instances in state End should have been dismissed and never show here."*/);
break;
case PStateName::FAIL:
throw std::exception(/*"Instances in state FAIL should have been dismissed and never show here."*/);
break;
default:
throw std::exception(/*"Fix me! Unknown state in a switch statement!"*/);
break;
}
}
typedef std::list<PState> StateList;
StateList nextChar( const StateList& actives, char c, size_t &counter )
{
StateList result;
for(auto fsm : actives)
{
PState fsm1 = Progress(fsm,c);
switch(fsm1.state)
{
case PStateName::FAIL: // Do nothing - weed out and do not count it.
break;
case PStateName::X1:
counter++;
result.push_back(fsm1);
break;
case PStateName::XN:
counter++;
result.push_back(fsm1);
break;
case PStateName::END:
counter++;
break;
default:
result.push_back(fsm1);
break;
}
}
result.push_back(PState::MakeX(c));
return result;
}
size_t countString( const std::string& s)
{
size_t counter = 0;
StateList current;
for(auto c : s)
{
current = nextChar(current,c,counter);
}
return counter;
}
size_t countFile( const std::string& filePath)
{
size_t counter = 0;
StateList current;
// TODO: read file char by char and feed it to nextChar as shown in the countString() function.
return counter;
}
int main(int argc, const char * argv[])
{
std::string s("abbaab");
std::cout <<"\"" << s << "\": " << countString(s) << std::endl;
return 0;
}