UVA - 644 - Immediate Decodability

传送门:

    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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值