csp20-06-3Markdown渲染器-学习版

本文介绍了如何使用C++编程实现一个Markdown解析器,处理文本中的段落、列表和空行,并计算渲染后的行数。作者提到在处理输入输出流时遇到困难,最终参考他人代码完成任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最开始不太会这里的输入输出操作,去补了一下getline,eof等c++输入输出的知识,但是后面自己debug不了,对输入输出流啥的没太明白,后面就放弃了自己写这道题,参考了其他大佬的思路顺着写了一遍,感觉思路很清晰的。哎,感觉败在了不会处理输入上了,后面发现不使用eof也是可以的。

//2006-3Markdown渲染器
#include<bits/stdc++.h>
using namespace std;
// 存每个段的结构
struct Mark {
	int type; 
	string s; 
}; 
vector<Mark> art;

// 判断是否为空行
bool isspace(string str) {
	for(int i=0; i<str.length(); i++) {
		if(str[i]!=' ') return false;
	}
	return true;
} 

// 除去行首尾空格
string standard(string str) {
	int pos1=0, pos2=str.length()-1;
	for(int i=0; i<str.length(); i++) {
		if(str[i]!=' ') {
			pos1 = i; break;
		}
	}
	for(int j=str.length()-1; j>=0; j--) {
		if(str[j]!=' ') {
			pos2 = j; break;
		}
	}
	string res=str.substr(pos1, pos2-pos1+1);
	return res;
} 

int main() {
	ios::sync_with_stdio(false);//因为大量的数据流所以需要加速
//	 cin.tie(0);
//	 cout.tie(0);
	int n;
	cin >> n; // 每行规格
	string str;
	
	// 可能以多个空行开始,要踢除
	while(getline(cin, str)) {
		if(!isspace(str)) break; // 不是空行 
	} 
	// 将第一行内容进行处理
	if(str.length()>=2&&str.substr(0,2)=="* ") // 列表文本
		art.push_back({1, standard(str.substr(2))});
	else // 普通段落
		art.push_back({2, standard(str)});
		
	bool check=false; // 用于判断前一行是否为空行
	while(getline(cin, str)) {
		if(isspace(str)) // 空行
			check = true;
		else { // 该行不是空行,根据上一行是否为空行,判断该行的处理方式 
			if(check) { // 上一行为空行 
				check = false;
				if(str.length()>=2&&str.substr(0,2)=="* ") 
					art.push_back({1, standard(str.substr(2))});
				else
					art.push_back({2, standard(str)});
			}
			else { // 上一行不为空行,考虑是否为同一段/同一个项目列表
				Mark &temp=art.back();
				if(temp.type==1||temp.type==3) { // 列表 
					if(str.length()>=2&&str.substr(0,2)=="  ") {
						temp.s += " ";
						temp.s += standard(str.substr(2));
					} 
					else if(str.length()>=2&&str.substr(0,2)=="* ") {
						// 非列表首项
						art.push_back({3, standard(str.substr(2))}); 
					}
					else {
						art.push_back({2, standard(str)}); // 普通段落 
					}
				} 
				else { // 上一行为段落
					if(str.length()>=2&&str.substr(0,2)=="* ") {
						art.push_back({1, standard(str.substr(2))});
					}
					else {
						temp.s += " ";
						temp.s += standard(str);
					}
					
				} 
				
			}
		} 
	} 
	// 读取完成----进行渲染计算行数
	long long ans=0;
	for(int i=0; i<art.size(); i++) {
		string& str=art[i].s;
		if(art[i].type!=3&&i>0) ans++;
		if(art[i].type!=2) {
			if(str.size()==0) ans++; // 空项目占一行
			else { // 同一项目要占三个空格
				for(int i=0; i<str.length(); i+=(n-3)) {
					while(i<str.length()&&str[i]==' ') i++; // 当位于行首的正好为空白字符,要删除
					ans++; 
				} 
			} 
		}
		else {
			for(int i=0; i<str.length(); i+=n) {
				while(i<str.length()&&str[i]==' ') i++;
				ans++;
			}
		}
	} 
	cout << ans << endl;
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值