1、问题描述
将给定字符串按U型进行输出。其中n1为左侧竖线包含的字符数,n2为底部横线包含的字符数,n3为右侧竖线包含的字符数,且n1,n2,n3均包含拐点处相交的字符,于是又n1+n2+n3=N+2恒成立。此外,对n1,n2,n3有如下的限制条件:
(1)n1==n3,即左侧竖线包含的字符数等于右侧竖线包含的字符数。
(2)n2>=n1,即底部横线包含的字符数总是不少于左、右单侧的竖线包含的字符数。
(3)在满足上面两个条件的前提下,使n1尽可能大。
注:每个输入示例不少于5个字符且不超过80个字符。
输入示例:
输出示例:
2、解法思想
首先,找到最优的情况(即在符合限制条件的情况下,最大的n1)。在下一部分有详细说明。
接着,把U字型分解成几个便于输出的图形。
3、关键函数详解
Part1:函数运行流程
——》开始;
——》输入字符串,同时调用strlen函数计算该字符串长度;
——》用do…while()循环,找到最优情况;
——》把U字型分块,用for循环输出;
——》结束;
Part2:求最优情况的方法
求法:用do…while()循环,设置好循环条件;
循环条件:本次n2>=n1,下次依旧n2>=n1;因为如果下次n2<n1,则说明这次就是最优情况;
具体代码:
do{ //使用do…while循环,计算符合限制条件的n1最大的情况;
n1++; //n1逐步增加,慢慢去试探;
n3=n1; //给n3赋值;
n2=n-n1-n3+2; //根据公式计算n2;
}while((n2>=n1)&&(n2-2>=n1+1)); //循环条件:本次n2>=n1,下次依旧n2>=n1;如果下次n2<n1,则说明这次就是最优情况;
Part3:分块输出U字型
废话不说了,直接上代码(有注释)
//开始分部分输出;
for(int i=0;i<n1-1;i++) //输出U型的上部(除了底边);
{ //上部:str[i] + n2-2个空格 + str[n-1-i] 总计n1-1行;
cout<<str[i]; //左边那列(除了最后一个);
for(int j=0;j<n2-2;j++)
{
cout<<" "; //空格;
}
cout<<str[n-1-i]<<endl; //右边那列(除了最后一个);
}
for(int r=0;r<n2;r++) //输出底部;
{
cout<<str[n1-1+r];
}
4、完整解法代码
#include<iostream>
#include<cstring> //在下面调用了strlen函数,要加头文件cstring;
using namespace std;
int n,n1=0,n2,n3; //定义所需的变量, 注:要给n1赋个初值,因为在下面需要对n1直接进行运算;
char str[81]; //定义一个字符串数组,存放所输入的字符,供下面输出使用;
void output()
{
cin>>str; //输入字符串数组直接输入,不需要for循环;
n=strlen(str); //获取字符串长度,并赋值给n;
do{ //使用do…while循环,计算符合限制条件的n1最大的情况;
n1++; //n1逐步增加,慢慢去试探;
n3=n1; //给n3赋值;
n2=n-n1-n3+2; //根据公式计算n2;
}while((n2>=n1)&&(n2-2>=n1+1)); //循环条件:本次n2>=n1,下次依旧n2>=n1;如果下次n2<n1,则说明这次就是最优情况;
//开始分部分输出;
for(int i=0;i<n1-1;i++) //输出U型的上部(除了底边);
{ //上部:str[i] + n2-2个空格 + str[n-1-i] 总计n1-1行;
cout<<str[i]; //左边那列(除了最后一个);
for(int j=0;j<n2-2;j++)
{
cout<<" "; //空格;
}
cout<<str[n-1-i]<<endl; //右边那列(除了最后一个);
}
for(int r=0;r<n2;r++) //输出底部;
{
cout<<str[n1-1+r];
}
}
int main()
{
output();
return 0;
}
5、运行结果
输出示例:helloworld!
运行环境:DEV c++
至此,整个题目解答完毕!!!
结语:以上就是我对这个问题的理解、解法,可能存在着更好、更简洁的解法代码,希望大家提出来,我们一起讨论,交换看法,共同进步。若上述代码中存在问题,望大家指正,谢谢大家看到结尾。(∩^∩)
奋斗的2351