C++算法——字幕校对问题

Posted eyes++

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++算法——字幕校对问题相关的知识,希望对你有一定的参考价值。

字幕校对问题

伴随着中国国产影视作品风靡国外,听不懂汉语的观众需要英文字幕的帮忙才能理解影片故事情节。现在小喇叭接到了这样一个任务,他需要按照标准.STA字幕格式的需要,对字幕文件进行编辑。标准英文字母格式如下:

[Ordinal number of the block]
[Beginning time of the subtitles --> Ending time of the subtitles]
[Subtitle text in one or more lines]

每两个字幕信息之间用一行空行隔开。时间格式为HH:MM:SS,TTT(注意是英文的冒号和逗号),表示 小时:分钟:秒,毫秒。 这是一个.STA格式文件的样例:

1
00:00:01,600 --> 00:00:04,200
Good day!
2
00:00:05,900 --> 00:00:07,999
Good day to you too!
Here you go!
3
00:00:10,000 --> 00:00:14,000
May I please have ten garlic sausages?

由于影片播放时需要对原有视频进行编辑以适应播出时长,所以字母文件也要做适当的调整,因此小喇叭的任务就是编写程序完成对字幕文件的编辑。
输入说明
每个测试样例最多不超过30行。第一行是字幕序号,第2行是按照.STA字幕格式的时间信息,第3行开始时字母信息,可能有多行字幕。为了便于处理,字幕中仅包含大小写字母和如下符号 ‘,.?!。(’。‘不含在内) ,最后一个字幕信息块后是一个’#'号,表明本测试样例末尾。 '#'号之后是一个整数T(-10000<=T<=10000),表示需要对字幕文件中时间信息进行调整的偏移量。
输出说明
按照给出的T(毫秒)编辑需求,调整字母文件中的时间信息(每个字幕块中的开始和结束时间)。并将修改好时间的字幕文件打印出来。测试数据保证编辑后的时间不会出现负值。

输入样例

8
00:00:01,600 --> 00:00:04,200
We thought you was…
9
00:00:05,900 --> 00:00:07,999
a toad.

300

输出样例

8
00:00:01,900 --> 00:00:04,500
We thought you was…
9
00:00:06,200 --> 00:00:08,299
a toad.

解题思路

首先很容易想到,该类的字符串处理题需要使用正则表达式经行处理,因为字幕的符号被限定,所以我们能根据每一行的字符特点利用正则表达式进行定位匹配,然后剩下的就是简单的数字处理。本题难点不在于复杂逻辑,而在于字符串处理。

首先利用空格和换行将各字段分为若干字符串,为了适应这样的储存方式我选择使STL库中的vector容器,然后创建两个正则表达式分别匹配“–>”和时间字符串里特有的“:”,首先输出序号,然后经行判断,如果遍历到”–>”,则将前后的字符串放入时间处理函数中,在事件处理函数中,将字符串里的时间数字取下化为数字类型,经行时间的增减操作,然后重新转换成字符串输出。对于非时间相关的字符串,则照常输出。

代码实现

#include<iostream>
#include<string>
#include<vector>
#include<regex>
using namespace std;

// 修改字幕出现时间
void corTime(string str, int delay)
{
	int h = (str[0] -48) * 10 + str[1] - 48;
	int min = (str[3] - 48) * 10 + str[4] - 48;
	int s = (str[6] - 48) * 10 + str[7] - 48;
	int ms = (str[9] - 48) * 100 + (str[10] - 48) * 10 + str[11] - 48;
	ms += delay;
	while(ms >= 1000)
	{
		ms -= 1000;
		s++;
		if(s >= 60)
		{
			min++;
			if(min >= 60)
				h++;
		}
	}
	if(h < 10)
		cout << "0" + to_string(h);
	else
	    cout << h;
	cout << ":";
	if(min < 10)
	    cout << "0" + to_string(min);
	else
	    cout << min;
	cout << ":";
	if(s < 10)
	    cout << "0" + to_string(s);
	else
	    cout << s;
	cout << ",";
	if(ms < 10)
	    cout << "00" + to_string(ms);
	else if(ms < 100)
	    cout << "0" + to_string(ms);
	else
	    cout << ms;
}

// 正常输出字幕 
void correct(vector<string>& s, int delay)
{
	regex reg("-->");
	regex reg2(".*:.*");
	int k = 0; 
	for(vector<string>::iterator it = s.begin(); it != s.end(); it++)
	{
		if(k == 0)
		{
			if(*(it + 2) == "-->")
			    continue;
			if(*(it + 2) == "#")
			    k = 1;
		}
		if(regex_match(*it, reg))
		{
			cout << endl << *(it - 2) << endl;
			corTime(*(it - 1), delay);
			cout << " --> ";
			corTime(*(it + 1), delay);
			cout << endl;
		}
		else if(regex_match(*it, reg2))
			continue;
		else if(*it == "#")
			cout << endl << *it;
		else
		    cout << *it << " ";
	}
}

int main()
{
	// 初始化题目条件 
    vector<string> s;
    string t;
    do
	{
		cin >> t; 
		s.push_back(t);
	}
	while(t != "#");
	int delay;
	cin >> delay;

	// 执行字幕校对操作 
    correct(s, delay);

	return 0;
}

展示

以上是关于C++算法——字幕校对问题的主要内容,如果未能解决你的问题,请参考以下文章

[新增ST-001片段]全程字幕-20套UML+Enterprise Architect建模示范视频

C++ 代码片段执行

[新增EA003考勤系统演示片段]全程字幕-22套UML+Enterprise Architect建模示范视频

这些 C++ 代码片段有啥作用?

AI大神李沐开源新手剪辑神器!只看字幕就能剪视频,卡壳重复片段一键删除...

有趣的 C++ 代码片段,有啥解释吗? [复制]