传送门:
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19143
题意:
Immediately定义,字符串数据组中,各字符串非其它字符串的前缀子串,就是immediately。
如存在字符串间存在前缀子串关系,则为非immediately。
注意:
① 各数据组以一行“9”结束。因此,边输入边处理的方法,注意要等到“9”才退出。
② 应用search进行搜索。
思路:
逐个输入字符串,边输入边处理。
① 对于当前字符串,判断其是否为其它字符串的前缀子串(当前Group,保存前面输入的)。
② 而后把当前字符串加入到目标组数据Group中。
其中逐个对比判断immediately代码,用search实现。
总结:
① 用STL,可以简化代码,把思路写得更具体化,可读性好。
但在效率上不够优化,看到用C直接写的,运行时间仅72ms,优化好多。待研究。
【使用STL容器,再读取,效率慢很多;即使相邻间对比(n复杂度)也一样慢;153ms;见代码B;
不使用容器,效率提升明显,62ms。见代码A。
效率与可视,要斟酌选择。】
② 这里使用了vector,如使用map会否更快效率?(因map会自动正序化)
【使用map只会使每加一次排序一次,推定会更慢。】
③ 这里使用了search,如换成find_if会不会更快?(网上有现成的find_if代码,
需要学习bind1st/bind2st/ptr_fun之类的,更简化代码)
【减少一个容器读取,推定速度相当。】
④ 如数据全输入完再进行判断处理,会不会更快?(因为省去多次判断和map的自动排序,
并且优先从小字符串开始比较)
【排序后并不怎么影响后面的效率,重点是复杂度问题可以改善明显。】
⑤ 现行不分长短顺序直接比较,“比较”复杂度n*(n-1)/2。如果按顺序来,好像还是一样的复杂度。。。
有没有可能减少?
【排序后,只需要相邻字符串进行子串对比。复杂度将为n。
而且,排序后,默认了前一位的字符串较短,方便比较】
⑥ string的strncmp用compare来实现,注意哪个是*this(pos,n)。
【见代码B】
原始代码:
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#include <string>
#include <stdio.h> //for freopen
using namespace std;
// Local Test
// #define LOCAL_TEST
// Define stringCompare Function for search(STL).
// Compare whether string a is equal b in length(min of two).
bool StrCompare(const string& a, const string& b)
{
int len = min(a.size(), b.size());
for ( int i=0; i<len; i++ )
if ( a[i] != b[i] )
return false;
return true;
}
int main()
{
// Local Test
#ifdef LOCAL_TEST
freopen("..\\in.txt", "r", stdin);
freopen("..\\out.txt", "w+", stdout);
#endif
// ------- Solution by using Sync(false)
std::ios::sync_with_stdio(false);
std::cin.tie(0);
// "Immediately" means that All datas in Group is not substring
// for others in Group.
// Define
bool bImmediately = true; // To be a flag of "Being Immediately".
string strLine; // string For input.
int nCase = 0; // Count of Cases.
vector<string> vGroup; // To Store Current Group datas.
vector<string> vToSearch; // To Store Current string data.
while ( !cin.eof() )
{
// Get data string.
getline(cin, strLine);
// Get data "9", meaning end of Current Group.
if ( strLine == "9" )
{
nCase++;
// Using bImmediately flag to determine.
if ( bImmediately )
cout <<"Set " <<nCase <<" is immediately decodable" <<endl;
else
cout <<"Set " <<nCase <<" is not immediately decodable" <<endl;
// Clear all data for starting Next Group.
vGroup.clear();
vToSearch.clear();
// Only Get "9" to end, set Flag to default "true".
bImmediately = true;
// end this group
continue;
} // end if
// While Group has been set "not immediately", then continue.
if ( !bImmediately )
continue;
// Clear Current string.
vToSearch.clear();
vToSearch.push_back(strLine);
// Using "search" to search vToSearch in Vector(vGroup),
// If it is found, return the corresponding iterator.
// Otherwise, return vGroup of end().
vector<string>::iterator it =
search(vGroup.begin(), vGroup.end(),
vToSearch.begin(), vToSearch.end(), StrCompare);
if ( it != vGroup.end() )
bImmediately = false;
// Store Current string to Group.
vGroup.push_back(strLine);
} // end while
return 0;
}
代码A:62ms
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// Local Test
// #define LOCAL_TEST
int cmp(const void *a, const void *b) {
return strcmp((char *)a, (char *)b);
}
int main() {
// Local Test
#ifdef LOCAL_TEST
freopen("..\\in.txt", "r", stdin);
freopen("..\\out.txt", "w+", stdout);
#endif
int t = 1, flag, i = 0, j;
char tmp[16], code[8][16];
while (gets(tmp) != NULL) {
if (*tmp == '9') {
qsort(code, i, sizeof(tmp), cmp);
for (flag = j = 0; j < i - 1; j++) {
if (strncmp(code[j], code[j + 1], strlen(code[j])) == 0) {
flag = 1;
break;
}
}
printf("Set %d is %simmediately decodable\n", t++, flag ? "not " : "");
i = 0;
continue;
}
snprintf(code[i++], sizeof(tmp), "%s", tmp);
}
return 0;
}
代码B: 153ms
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#include <string>
#include <stdio.h> //for freopen
using namespace std;
// Local Test
// #define LOCAL_TEST
int main()
{
// Local Test
#ifdef LOCAL_TEST
freopen("..\\in.txt", "r", stdin);
freopen("..\\out.txt", "w+", stdout);
#endif
// ------- Solution by using Sync(false)
std::ios::sync_with_stdio(false);
std::cin.tie(0);
// "Immediately" means that All datas in Group is not substring
// for others in Group.
// Define
bool bImmediately = true; // To be a flag of "Being Immediately".
string strLine; // string For input.
int nCase = 0; // Count of Cases.
vector<string> vGroup; // To Store Current Group datas.
int i;
while ( !cin.eof() )
{
// Get data string.
getline(cin, strLine);
// Get data "9", meaning end of Current Group.
if ( strLine == "9" )
{
nCase++;
// sort in ascending order
sort(vGroup.begin(), vGroup.end());
for ( i=0; i+1<vGroup.size(); i++ )
if ( vGroup[i+1].compare(0, vGroup[i].size(), vGroup[i]) == 0 )
{
bImmediately = false;
break;
} // end if
// Using bImmediately flag to determine.
if ( bImmediately )
cout <<"Set " <<nCase <<" is immediately decodable" <<endl;
else
cout <<"Set " <<nCase <<" is not immediately decodable" <<endl;
// Clear all data for starting Next Group.
vGroup.clear();
// Only Get "9" to end, set Flag to default "true".
bImmediately = true;
// end this group
continue;
} // end if
// Store Current string to Group.
vGroup.push_back(strLine);
} // end while
return 0;
}