前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >POJ 2797 最短前缀(贪心算法)

POJ 2797 最短前缀(贪心算法)

作者头像
天道Vax的时间宝藏
发布2021-08-11 10:39:58
4340
发布2021-08-11 10:39:58
举报
文章被收录于专栏:用户5305560的专栏

题目:最短前缀

一个字符串的前缀是从该字符串的第一个字符起始的一个子串。例如 "carbon"的字串是: "c", "ca", "car", "carb", "carbo", 和 "carbon"。注意到这里我们不认为空串是字串, 但是每个非空串是它自身的字串. 我们现在希望能用前缀来缩略的表示单词。例如, "carbohydrate" 通常用"carb"来缩略表示. 现在给你一组单词, 要求你找到唯一标识每个单词的最短前缀 在下面的例子中,"carbohydrate" 能被缩略成"carboh", 但是不能被缩略成"carbo" (或其余更短的前缀) 因为已经有一个单词用"carbo"开始 一个精确匹配会覆盖一个前缀匹配,例如,前缀"car"精确匹配单词"car". 因此 "car" 是 "car"的缩略语是没有二义性的 , “car”不会被当成"carriage"或者任何在列表中以"car"开始的单词.

Input

  • 输入包括至少2行,至多1000行. 每行包括一个以小写字母组成的单词,单词长度至少是1,至多是20.

Output

  • 输出的行数与输入的行数相同。每行输出由相应行输入的单词开始,后面跟着一个空格接下来是相应单词的没有二义性的最短前缀标识符。

Sample Input

代码语言:javascript
复制
carbohydrate
cart
carburetor
caramel
caribou
carbonic
cartilage
carbon
carriage
carton
car
carbonate

Sample Output

代码语言:javascript
复制
carbohydrate carboh
cart cart
carburetor carbu
caramel cara
caribou cari
carbonic carboni
cartilage carti
carbon carbon
carriage carr
carton carto
car car
carbonate carbona

题意理解:

  1. 首先需要建立三个数组,两个字符型数组保存字符串和最短前缀,一个整形数组保存字符串的长度。
  2. 输入结束后,总体结构设置三个循环,i,j,k,for(i)循环第i个字符串,for(j)循环从每个字符串的第一个字符开始,长度为1~strlen(str)的子串,for(k)循环使当前子串ten与其他的第j个字符串进行比较。
  3. 用strstr()函数判断当前字符串的子串ten是否是其他字符串的子串。若是,ten子串字符+1,若不是,则输出当前子串ten。
  4. 最后如果判断子串与字符串本身相同,也要使其输出。

代码:

代码语言:javascript
复制
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<deque>
#include<fstream>
#include<iomanip>
#include<map>
#include<queue>
#include<string>
#include<set>
#include<stack>
#include<vector>
typedef long long ll;
using namespace std;
char str[1002][22];
int strl[1002];
char ten[22];

int main()
{
	int count=0;
	while((scanf("%s",&str[count]))!=EOF)
	{
		strl[count]=strlen(str[count]);

		count++;
	}
	/*for(int i=0;i<count;i++)
	{
		cout<<strl[i]<<endl;
	}*/
	int i,j,k;
	for(i=0;i<count;i++)//挨个查找每个单词的唯一前缀
	{
		for(j=1;j<=strl[i];j++)//!!!!!!!!!!
		//挨个查找该字符串的前缀是否唯一标识,注意子串长度从1开始,空串不是子串
		{
			memset(ten,0,sizeof(ten));
			for(k=0;k<j;k++)
			{
				ten[k]=str[i][k];
			}
			ten[k]='\0';//使用ten数组暂时保存要判断是否唯一的子串
			for(k=0;k<count;k++)
			{
				if(k!=i)//判断子串是否是其他字符串的字符串
				{
					if(strstr(str[k],ten)==str[k])
					    break;
				}
			}
			if(k==count){//如果不是,打印,跳出循环找下一个串的表一最短前缀
				cout<<str[i]<<" "<<ten<<endl;
				break;
			}
		}
		if(j==strl[i]+1) cout<<str[i]<<" "<<str[i]<<endl;
		//如果字符串本身也是其他串的子串则打印该串本身
	}
	return 0;
		
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/08/03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目:最短前缀
    • Input
      • Output
        • Sample Input
          • Sample Output
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档