问题:在平面上模拟两个变速齿轮的咬合,为了能在一块最短的合金上割出这两个齿轮,需要将两个齿轮的序列进行匹配。
输入:一串字符表示底部齿轮(master),1表示凹陷,2表示牙凸
一串字符表示上部齿轮(driven),1表示凹陷,2表示牙凸
输出:将两个字符串进行匹配,输出至少需要多长的合金板才能切出这两个齿轮
思路:从底部字符串开始,寻找一个与上部字符串匹配的子串,如果没找到则一直后移。
过程:①从底部字符串的第一个字符开始,寻找与上部字符串匹配的子串
②如果第一个字符不匹配,则顺序延伸。
③如果最后匹配到的位置小于底部字符串的大小,则长度为底部字符串;
④如果匹配到的配置长于底部字符串,则长度为底部字符串开始匹配的位置+顶部字符串的长度;
#include <iostream>
#include <string>
using namespace std;
int lcompute(const string &master, const string &driven)
{
for (string::const_iterator iter = master.begin(); iter != master.end(); ++iter) {
for (string::const_iterator m = iter, d = driven.begin(); m < master.end() && d < driven.end();++m, ++d) {
if (*m != *d || *m == '1') {// 两个凹处也可以贴合,太粗心了
if ((m + 1) == master.end())
return master.size() + (driven.end() - d - 1 );
else if ((d + 1) == driven.end())
return master.size();
else
continue;
}//endif
else
break;
}//endfor
}//endfor
return master.size() + driven.size();
}
int main()
{
#ifndef UVa
FILE *fp;
freopen_s(&fp, "data.in.txt", "r", stdin);
freopen_s(&fp, "data.out.txt", "w", stdout);
#endif
string bottom;
string up;
int lbtm = 0;
int lup = 0;
while (cin >> bottom >> up) {
lbtm = lcompute(bottom, up);
lup = lcompute(up, bottom);
if (lbtm > bottom.size() + up.size())
cout << "error" << endl;
if (lup > bottom.size() + up.size())
cout << "error" << endl;
if (lbtm < lup)
cout << lbtm << endl;
else
cout << lup << endl;
}
return 0;
}