字符串

  • 7-1 对称排序 (25 分)

你供职于由一群丑星作为台柱子的信天翁马戏团。你刚完成了一个程序编写,它按明星们姓名字符串的长度非降序(即当前姓名的长度至少与前一个姓名长度一样)顺序输出他们的名单。然而,你的老板不喜欢这种输出格式,提议输出的首、尾名字长度较短,而中间部分长度稍长,显得有对称性。老板说的具体办法是对已按长度排好序的名单逐对处理,将前者放于当前序列的首部,后者放在尾部。如输入样例中的第一个案例,Bo和Pat是首对名字,Jean和Kevin是第二对,余此类推。

输入格式:

输入包含若干个测试案例。每个案例的第一行含一个整数n(n>=1),表示名字串个数。接下来n行每行为一个名字串,这些串是按长度排列的。名字串中不包含空格,每个串至少包含一个字符。n=0为输入结束的标志。

输出格式:

对每一个测试案例,先输出一行“Set n”,其中n从1开始取值,表示案例序号。接着是n行名字输出,如输出样例所示。

输入样例:

7
Bo
Pat
Jean
Kevin
Claude
William
Marybeth
6
Jim
Ben
Zoe
Joey
Frederick
Annabelle
5
John
Bill
Fran
Stan
Cece
0

输出样例:

SET 1
Bo
Jean
Claude
Marybeth
William
Kevin
Pat
SET 2
Jim
Zoe
Frederick
Annabelle
Joey
Ben
SET 3
John
Fran
Cece
Stan
Bill
#include<iostream>
#include<cstring>

using namespace std;


int main(){
	int n;
	int w=0;
	while(1){
		cin>>n;
		if(n==0) break;
		string s[n],e[n];
		for(int i=0;i<n;i++) cin>>s[i];
		for(int i=0,j=n-1,k=0;i<n;j--,k++){
			e[k]=s[i];
			//cout<<e[k]<<endl;
			i=i+1; 
			if(i>=n) break;
			e[j]=s[i];
			i=i+1;
		}
		w++;
		printf("SET %d\n",w);
		for(int i=0;i<n;i++){
			cout<<e[i]<<endl;
		}
	}
}
#include<iostream>
#include<cstring>

using namespace std;


int main(){
	int n;
	int w=0;
	while(1){
		cin>>n;
		if(n==0) break;
		
		string s[n];
		for(int i=0;i<n;i++) cin>>s[i];
		w++;
		printf("SET %d\n",w);
		for(int i=0;i<n;i++){
			if(i%2==0)
				cout<<s[i]<<endl;
		}
		for(int i=n-1;i>=0;i--){
			if(i%2==1)
				cout<<s[i]<<endl;
		}
	}
}

 

 

  • 7-2 字符串输入练习 (I) (15 分)

计算字符串的长度。

输入格式:

每行一个字符串。

输出格式:

针对每行字符串,输出该串的长度。

输入样例:

hello world!
welcome to acm world

输出样例:

在这里给出相应的输出。例如:

12
20

理解错了题目,以为是循环读入字符串,一直从键盘读入,最后Ctrl+Z停止输入:

C语言

#include<stdio.h>
#include<cstring>

int main(){
	char s[100];      
	while(gets(s)){
		printf("%d\n",strlen(s));
	}
}

然而gets在C11标准中已被正式删除,编译不通过。

cin读入遇空格就结束输入。

变量为string类型,不是字符数组,考虑getline()函数

#include<iostream>
#include<cstring>
using namespace std;

int main(){
	string a;
	while(getline(cin,a)){
		cout<<a.size()<<endl;
	}
}

还可以考虑cin.get(char *str,int maxnum) 和 cin.getline(char *str,int maxnum)  可接收空格,遇回车结束输入。

int main()
{
    char st[50]; 
    cin.getline(a,50);
    //cin.get(a,50);
    cout<<a<<endl;
}

 

  • 7-3 20052 字符串排序 (15 分)

从键盘输入10个字符串,从小到大排序并输出。

输入格式:

10个字符串。

输出格式:

排序后的10个字符串。

输入样例:

apple
pear
people
hello
is
are
Disk Operating System
dis
notebook
Hi Li

输出样例:

在这里给出相应的输出。例如:

Disk Operating System
Hi Li
apple
are
dis
hello
is
notebook
pear
people

 

又把题目看错了,不是比较字符串的长度,而是大小

#include<algorithm>
using namespace std;

struct P{
	string c;
	int num;
}T[10];


bool compare(P a,P b){
	return a.num>b.num;
}

int main(){
	for(int i=0;i<10;i++){
		getline(cin,T[i].c);
		T[i].num=T[i].c.size();
	}
	sort(T,T+10,compare);
	for(int i=0;i<10;i++)
	cout<<T[i].c<<endl;	
}

修改后的AC代码:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

string T[10];

bool compare(string a,string b){
	if(a<b) return true;
	else return false;
}

int main(){
	for(int i=0;i<10;i++){
		getline(cin,T[i]);
	}
	sort(T,T+10,compare);
	for(int i=0;i<10;i++)
	cout<<T[i]<<endl;	
}

C++添加的string字符串是一个类,该类对运算符>、<和==进行了重载,能够直接比较两个字符串的大小。

C语言中的字符串常用strcmp比较大小。

 

  • 7-4 30057 判断一个字符串是否是另一个字符串的子串 (15 分)

判断一个字符串是否是另一个字符串的子串。如字符串s1=”onetwothreeforth”,字符串s2=”for”,即s2是s1的子串,程序输出”YES!”,否则输出”NO!”。假如strlen(s1)>= strlen(s2)。

输入格式:

输入两个字符串。

输出格式:

s2是s1的子串,程序输出“YES!”,否则输出"NO!”。

输入样例:

onetwothreeforth
for

输出样例:

YES!

输入样例:

onetwothreeforth
the

输出样例:

NO!
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

int main(){
	char a[10000],b[10000];
	cin.get(a,10000);
	getchar();
	cin.get(b,10000);
	int j=0;int flag=1;
	
	for(int i=0;i<strlen(a);i++){
		if(a[i]==b[j]){
			j++;
			if(j==strlen(b)) {
				flag=0;
				break;
			}
		}
		else j=0;
	}
	
	if(flag) printf("NO!");
	else printf("YES!");
}

才开始用cin.get() 发现需要在中间加getchar()

 

  • 7-6 值班安排 (50 分)

医院有A、B、C、D、E、F、G 7位大夫,在一星期内(星期一至星期天)每人要轮流值班一天,如果已知: (1)A大夫比C大夫晚1天值班; (2)D大夫比E大夫晚1天值班; (3)E大夫比B大夫早2天值班 (4)B大夫比G大夫早4天值班; (5)F大夫比B大夫晚1天值班; (6)F大夫比C大夫早1天值班; (7)F大夫星期四值班。 就可以确定周一至周日的值班人员分别为:E、D、B、F、C、A、G。 编写程序,根据输入的条件,输出星期一至星期天的值班人员。

输入格式:

先输入一个整数n,再输入n组条件,要求能够根据输入的条件确定唯一的值班表,且输入的n组条件中能够直接或间接得到任意两位大夫的关联关系,例如上面的条件(2)直接显示了D与E间的关系,而通过条件(1)、(6)、(5)可以间接得到A与B的关系。 条件的输入格式有2种: 格式1:编号 比较运算符 编号 天数 其中比较运算符有2种:> 或 < ,分别表示“早”或“晚” 例如:A<C1 表示:A大夫比C大夫晚1天值班 格式2:编号 = 数值 例如:F=4 表示:F大夫在星期四值班

输出格式:

输出周一至周日的值班序列。

输入样例:

7
A<C1
D<E1
E>B2
B>G4
F<B1
F>C1
F=4

输出样例:

EDBFCAG

 以前写过一次,又重新写了一次,主要的算法相同,但是存储结构不同,第一次存储的是所有输入的字符串,第二次全部转化成二维数组,类似于图;

第二次AC代码:

#include<iostream>
#include<cstdio>
#include<cstring> 
#include<algorithm>

using namespace std;

char t[7][7];
int vist[7];

struct point{ //结构体,方便排序 
	char str;
	int week;
}w[7];

int N;

void dfs(int x){
	vist[x]=1;
	for(int i=0;i<N;i++){
		if(vist[i]==1) continue;
		if(t[x][i]){
			w[i].str=i+'A';
			w[i].week=w[x].week+t[x][i];
			dfs(i);
		}
	}
}

bool compare(point a,point b){
	return a.week<b.week;
}

int main(){
	cin>>N;int begin;
	
	for(int i=0;i<N;i++){
		char s[5];
		scanf("%s",s);
		if(s[1]=='=') {
			begin=s[0]-'A'; //!!
			w[s[0]-'A'].str=s[0];
			w[s[0]-'A'].week=s[2]-'0';
		}
		else{
			if(s[1]=='<'){
				t[s[0]-'A'][s[2]-'A']=s[3]-'0';
				t[s[2]-'A'][s[0]-'A']=-(s[3]-'0');
			}
			else{
				t[s[0]-'A'][s[2]-'A']=-(s[3]-'0');  //忘记-‘0’了 
				t[s[2]-'A'][s[0]-'A']=s[3]-'0';
			}
		}
	}
	dfs(begin);
	sort(w,w+7,compare);
	for(int i=6;i>=0;i--) printf("%c",w[i].str);
}

第一次AC代码:第一次写得很辛苦,字符和int不断的转换,很容易错漏:

//不想再看第二遍的代码
#include<iostream>
#include<cstdio>
#include<string.h> 

using namespace std;

char mess[9][5];
int N;
char a[8];
int vist[9];


void print(){
	for(int j=1;j<8;j++){
		printf("%c",a[j]);
	}
	printf("\n");
}

void dfs(char x,int y){
	
	for(int i=0;i<N;i++){
		if(vist[i]==-1) continue;
	    if(mess[i][0]==x){
			if(mess[i][1]=='<'){
				int q=mess[i][3]-'0';
			
				a[y-(mess[i][3]-'0')]=mess[i][2];
				//vist[y+(mess[i][3]-'0')]=-1;
				//vist 的参数 不能与a相同 
				vist[i]=-1;	//两次遍历到了同一行字符 
				dfs(mess[i][2],y-(mess[i][3]-'0'));
			}
			else if(mess[i][1]=='>'){
				a[y+(mess[i][3]-'0')]=mess[i][2];
				vist[i]=-1;
				dfs(mess[i][2],y+(mess[i][3]-'0'));
			}
			
		}
		if(mess[i][2]==x){
			if(mess[i][1]=='<'){
				a[y+(mess[i][3]-'0')]=mess[i][0];
				vist[i]=-1;
				dfs(mess[i][0],y+(mess[i][3]-'0'));
			}
			else{
				a[y-(mess[i][3]-'0')]=mess[i][0];
				vist[i]=-1;
				dfs(mess[i][0],y-(mess[i][3]-'0'));
			}
		}
	
	}
}

int main(){
	cin>>N;
	int mark=-1;
	for(int i=0;i<N;i++){
		scanf("%s",mess[i]);
		if(mess[i][1]=='=') mark=i;
	}
	a[mess[mark][2]-'0']=mess[mark][0];//错误a[mess[mark][2]] 字符转int一定要-‘0’ 
	char q1=mess[mark][0];
	vist[mark]=-1;
	 
    dfs(q1,mess[mark][2]-'0');
	print();
	return 0;
}
	
	/*
	1.问题:
	     mess[4][0]==q1   mess[5][0]==q1  正向循环为什么先循环了5
		 if(mess[4][0]==q1) printf("1!!!!!!!");
		 
	  解决:
	    Vist数组 中的i 不是 字符串的i  主函数vist参数错了,应该等同于字符串的行数 
		每次vist 都忽略了4 
 */ 
  • 7-7 二维数组每列排序 (10 分)

一个4×5的整型二维数组,从键盘输入数据,并对该数组的每一列按从小到大的顺序排列后输出。

输入格式:

输入4行5列的矩阵,每行第一个数前没有空格,每行的每个数之间各有一个空格。

输出格式:

输出4行5列的矩阵,每行第一个数前没有空格,每个数输出占4列列宽。

输入样例:

5 1 1 4 2
1 2 3 4 5
8 4 5 2 1
7 5 3 6 4

输出样例:

   1   1   1   2   1
   5   2   3   4   2
   7   4   3   4   4
   8   5   5   6   5

这是一道和字符串没有关系的二维数组的题目

就是发现加了空格反而没办法AC,所以注释掉了

列出一部分具体的点来看希望转化成的数组是什么样子的,不容易出错

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

int main(){
	int s[5][4];

	for(int i=0;i<4;i++){
		for(int j=0;j<5;j++)
			scanf("%d",&s[j][i]);
	}
	
	/*显示转换后的矩阵	
	for(int i=0;i<5;i++){
		for(int j=0;j<4;j++){
			printf("%d ",s[i][j]);
		}
		printf("\n");
	}
	*/
	 
	for(int i=0;i<5;i++)
		sort(s[i],s[i]+4);
		
	for(int i=0;i<4;i++){
		for(int j=0;j<5;j++){
			//if(j!=0) printf(" ");
			printf("%4d",s[j][i]);
		}
		printf("\n");
	}
}

 %4d 列宽为4 (要输出%d只需在前面再加上一个%,要输出\只需在前面再加上一个\,要输出双引号也只需在前面加上一个\即可)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值