Hello World for U

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函数计算该字符串长度;
 ——》用dowhile()循环,找到最优情况;
 ——》把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

发布了15 篇原创文章 · 获赞 3 · 访问量 869

猜你喜欢

转载自blog.csdn.net/weixin_45620022/article/details/105167179