不及格的小A 360笔试 C++

题目描述:
小A的英语考了个不及格,老师很生气,并且发现他英语的语法几乎全错!于是老师决定好好教教他英语语法。
老师想先从句子结构开始教他。一个句子至少需要包含主谓结构,即主语和谓语,并且主语在前,谓语在后。
有些句子会在谓语后面加上宾语。避免复杂,本题中句子的顺序严格按照主语-谓语-宾语的顺序(即无宾语前置和倒装等情况)。
老师给了小A三张单词表,分别是主语单词表、谓语单词表和宾语单词表。老师要让小A用这些单词表中的单词来造句,
并且规定:谓语有且仅有一个单词,主语和宾语可以包含任意个单词(主语不可为空)。
老师暂时不想让小A造出能保证意思通顺的句子,他只想让小A能够学会基本的句子结构就行。
现在,小A根据这些单词造了m条句子,现在假设你是老师,你需要判断每条句子是否符合上述句子结构。

输入描述
  第一行三个正整数n1,n2,n3,分别表示主语、谓语、宾语单词表的单词数;
  第二行包含n1个单词,单词仅由小写英文字母组成,每两个单词之间有一个空格,单词长度不超过10;
  第三行包含n2个单词,其他格式同上;
  第四行包含n3个单词,其他格式同上;
  第五行一个正整数m;
  接下来m行,每行一个句子。句子由若干单词(至少一个)组成,并且保证出现的单词都在上面的单词表内。每两个单词之间一个空格隔开。
  数据保证一个单词最多只可做一种句子成分。即每个单词仅会出现在一个单词表上。
  1≤n1,n2,n3≤1000,1≤m≤20,1≤句子单词数≤10

  输出描述
  对于每条句子,如果其符合句子结构,输出一行“YES”(不含引号),否则输出一行“NO”(不含引号)。


样例输入
    3 3 3
    i you he
    am is are
    yours his hers
    5
    i am yours
    you is his
    he are hers yours
    i am am yours
    is his
样例输出
    YES
    YES
    YES
    NO
    NO
用C++代码实现,思路:把主谓宾用unordered_set<string>放起来,方便查找。然后把每个句子都拆成单词放入vector<vector<string>>中。输入完后,处理每一个句子看是那种情况,输出”NO”,”YES”.
代码如下:
#include <bits/stdc++.h>
using namespace std;

int main(void)
{
  int n1 = 0, n2 = 0, n3 = 0, m = 0;
  unordered_set<string> s1; // 主语
  unordered_set<string> s2; // 谓语
  unordered_set<string> s3; // 宾语
  
  cin >> n1;
  cin >> n2;
  cin >> n3;
  string temp;
  
  for(int i = 0; i < n1; i++) {
    cin >> temp;
    s1.insert(temp);
  }
  for(int i = 0; i < n2; i++) {
    cin >> temp;
    s2.insert(temp);
  }
  for(int i = 0; i < n3; i++) {
    cin >> temp;
    s3.insert(temp);
  }
  cin.clear();
  cin >> m;
//  cout << endl << "m : " <<  m << ", s1.size(): " << s1.size() << ", s2.size(): " << s2.size() << ", s3.size(): " << s3.size() << endl;
  cin.get(); // 去掉换行
   
  vector< vector<string> >  v;
  
  for(int i = 0; i < m; i++) { // m个句子输入
    vector<string> vTemp;
    char c;
    temp.clear();
    c = cin.get();
    while( c != '\n' ) {
    	
		if(c == ' ' ) {
//			cout << temp; 
			vTemp.push_back(temp);
			temp.clear();
		}
		else {
		    temp += c;
		}
        c = cin.get();
    }
    
	vTemp.push_back(temp);
    
    v.push_back(vTemp);
    
//    getline(cin, temp);   //行读取 
//    v[i] = temp;
  }

// 调试代码,看句子输入是否正确  
//  cout << endl;
//  for(int i = 0; i < m; i++) {
//  	for( int j = 0; j < v[i].size(); j++){
//	  	cout << v[i][j] << " " ;
//	  }
//  	cout << endl << "111\n";
//  }
//  cout << endl;
  
  
  // 现在开始处理数据
  for(int i = 0; i < m; i++) {
	    if(v[i].size() == 0)
	    {
	      cout << "NO" << endl;
	      continue;
	    }
	    int s = v[i].size(); // 一行的元素大小
	    int zhu = 0, wei = 0, bing = 0; // 主谓宾个数 
	    
	    for(int j = 0; j < s; j++) {
	      if( s1.find(v[i][j]) != s1.end() ) { // 主语 
	        zhu++;
	      } else if(s2.find(v[i][j]) != s2.end()) {
	        wei++;
	        if( (wei == 1 && zhu == 0) || wei == 2) { // 没主语有谓语 和 两个谓语的情况 
				cout << "NO" << endl;
				break;
			}
	      } else if(s3.find(v[i][j]) != s3.end()) {
	        bing++;
	        if(zhu == 0 && wei == 1 && bing == 1) { //  没主语有谓语和宾语 
				cout << "NO" << endl;
				break;
			} 
	      } 
		   
		  if(j == s-1) {
		  	cout << "YES" << endl;
		  } 
	    }
		
   }
  return 0;
}

**复盘总结:**我把输入的cin和getline的具体用法忘记了,调试了半天没弄对。晚上做该题总结:

  1. cin 后用cin.get(),getline() 的问题(已经翻车两次了,输入老有问题):
    用cin会自动忽略换行,然后再用其他函数读。情况1:用cin.get()直接读数据会读到一个换行,需要用一个cin.get()把换行读出来再用cin.get()去读数据;情况2:用getline也会出现读到换行符的情况。

  2. cin.get读取一个字符
    可以使用cin.get()或者cin.get(var)两种方式,可以读出一个字符(空格,换行等)。

  3. cin.get 读取一行,缓冲区还有一个换行符不被清理
    可以用istream& get(char* s, streamsize n) 或者 istream& get(char* s, size_t n, streamsize delim)区别前者默认以换行符结束,后者可以指定结束符; n表示目标空间的大小。可以用cin.get()或者cin.ignore()来清理

  4. cin.getline读取一行,会自动清理缓冲区的换行符

istream& getline(char* s, streamsize count);
istream& getline(char* s, streamsize count, char delim);
#include<iostream>
using namespace std;

int main(void)
{
	char a;
	char array[20] = {NULL};
	// 输入123456789换行时 
//	cin.get(array, 20); // 123456789 
//	cin.get(a); // 读换行 
	
//	cout << array << " " << (int)a << endl; // 123456789 10
	 
	 // 输入123456789换行换行   注意两个换行才能读到a的换行 
	cin.getline(array, 20); // cin.getline(array, 20, '\n');
	cin.get(a);
	cout << array << " " << (int)a << endl; //  123456789 10
	
	
	return 0;
} 
  1. getline读取一行,在std命名空间的全局函数,参数使用了string字符串。
    getline利用cin可以从标准输入设备键盘读取一行,当遇到如下三种情况结束读操作:
    1)到文件结束
    2)遇到函数的定界符
    3)输入达到最大限度
istream& getline(istream& is, string str);
istream& getline(istream& is, string str, char delim);

6.申请vector<vector<string>> v(m),然后后边用v.push_back(temp)放数据,导致前面数据没放对位置;正确应该是v[i] = temp

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值