蓝桥杯 控制台画表格 字符串处理



画表格


在图形环境中很容易做出漂亮的表格。但在控制台环境中就比较困难了。有的时候可以用一些符号大略地模拟:(word文档中可能不整齐,拷贝到记事本中看)

本题目要求设计一个程序,把用户输入的内容用这种“准表格”的方式展现出来。具体的要求是:
用户输入的第一行是一个整数,表示接下来有多少行信息。接下来的每行由若干单元组成。单元间用逗号分开。
程序输出:用表格方式重新展现的输入内容。
例如:


用户输入:
3
cat,dog,good-luck
1,2,5
do not use,,that
则程序输出:(word文档中可能不整齐,拷贝到记事本中看)

蓝桥杯 控制台画表格 字符串处理_第1张图片

从中不难看出:
两个连续的逗号表示中间有一个内容为空的单元
列的数目由最大的单元数的那行决定
列的宽度由同列的最宽的单元决定
单元格中的信息左对齐


可以假设:用户输入的最大行数为30,可能的最多列数为40。


做完这道题,感觉整个人都不好了,对字符串处理的题目表示无爱。。。


这道题目个人感觉还是字符串处理中一道比较有意思也比较麻烦的题目,输入几个字符串,将它们填到一个符合题目要求的表格中去,首先让我们来明确一下思路:


一、首先,当然是把字符串输进去,这个地方其实还真有点技巧,因为字符串中可能存在空格,所以不能用cin,如果要是用gets的话,又会把回车也读到串中,而且存在种种未知错误,最终我使用了cin.getline(str,n),然后还需要在上面输入行数r的下面加上一个getchar(),吸收掉结尾的回车,我定义了一个char类型的二维数组,通过上面的方法将每个串输出到数组当中。


二、因为题目说每一列的宽度是每一列中最长的那个串的长度,所以我们使用一个函数获得每一列的宽度,我先建立了一个以为数组用以保存每一列的宽度,然后分别扫描每一个字符串,当得到一个比原来的宽度还要宽的串后,就把这个更大的数值保存在数组中,通过这一步,就获得了每一列的宽度。


三、经过上面两步,我们就可以开始绘制表格了,我们已经知道了这个表格的列数c和行数r,但实际上要打印的行数logic_r=2*r+1,也就是说到打印这么多行,其中奇数行都是一样的,打印"+"和"-",这个比较简单,只要在相应的位置上输出就可以,偶数行则是显示"|"和数据以及空格,这个比较麻烦我的做法就是从前往后扫描,在特定的位置上输出"|",其他位置则是输出数据和空格,以","和末尾为节点标志,具体的做法可以看代码

#include<iostream>
#include<stdio.h>
#include<memory.h>
#include<cstring>
using namespace std;

void getMaxWidth(char *str,int *c_width)//获得表格的每列的宽度,就是找字符串的长度 ,更长的代替次长的 
{
	int i,c,count;
	count=0;
	c=0;
	for(i=0;i<strlen(str);i++)
	{
		if(str[i]!=',')
		{
			for(;str[i]!=','&&i<strlen(str);i++)
			count++;
		}
		if(c_width[c]<count)
		c_width[c]=count;
		c++;
		count=0;
	}
	
}



int main()
{
	char data[40][500];
	int r,c,i,j,k,l,c_width[50],logic_r;
	memset(c_width,-1,sizeof(c_width));
	cin>>r;
	getchar();
	for(i=0;i<r;i++)
	{
		cin.getline(data[i],500);
	}
	for(i=0;i<r;i++)
	{
		getMaxWidth(data[i],c_width);
	}
	for(i=0;i<50;i++)
	{
		if(c_width[i]==-1)
		{
			c=i;
			break;
		}
	
	}
	int num=0;
	for(i=0;;i++)//对存储列长的数组进行处理,将长度映射成位置,如长度为1,2,3,那么位置就是1,3,6 
	{
		if(c_width[i]!=-1)
		{
			num+=c_width[i];
			if(i>0)
			c_width[i]+=c_width[i-1]+1;
		}
		else
		{
			num+=i+1;
			break;
		}
	}
	logic_r=2*r+1;//算出到底要打印几行 
	for(i=1;i<=logic_r;i++)//开始打印 
	{
		if(i%2==1)//奇数行的时候,只需要打印"+"和"-" 
		{
			for(j=0;j<num;j++)
			{
				bool flag=1;
				if(j==0)
				{
					cout<<'+';
					flag=0;
				}
				for(k=0;k<c;k++)
				if(j==c_width[k]+1)
				{
					cout<<'+';
					flag=0;
				}
				if(flag)
				cout<<'-';
				
			}
			cout<<endl;
		}
		l=0;
		int p=0;
		if(i%2==0)//偶数行的时候,打印"|"和数据以及空格 
		{
			for(j=0;j<num;j++)
			{
				bool flag=1;
				if(j==0)
				{
					cout<<'|';
					flag=0;
				}
				for(k=0;k<c;k++)
				if(j==c_width[k]+1)
				{
					cout<<'|';
					flag=0;
				}
				if(flag)
				{
					if(l>strlen(data[i/2-1]))
					cout<<' ';
					for(;l<=strlen(data[i/2-1]);l++)
					{
						if(data[i/2-1][l]!=','&&l<strlen(data[i/2-1]))
						{
							j++;
							cout<<data[i/2-1][l];
						}
						if(data[i/2-1][l]==','||l==strlen(data[i/2-1]))
						{
							l++;
							for(;j<=c_width[p];j++)
							cout<<' ';
							j--;
							p++;
							break;
						}
					}
					
				}
			}
			cout<<endl;
		}
		
	}
	return 0;
}




你可能感兴趣的:(ACM,字符串处理,蓝桥杯,控制台画表格)