(PAT Basic)1029.旧键盘(字符匹配) C++

原题:https://pintia.cn/problem-sets/994805260223102976/problems/994805292322111488

旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现。现在给出应该输入的一段文字、以及实际被输入的文字,请你列出肯定坏掉的那些键。

输入格式:
输入在 2 行中分别给出应该输入的文字、以及实际被输入的文字。每段文字是不超过 80 个字符的串,由字母 A-Z(包括大、小写)、数字 0-9、以及下划线 _(代表空格)组成。题目保证 2 个字符串均非空。

输出格式:
按照发现顺序,在一行中输出坏掉的键。其中英文字母只输出大写,每个坏键只输出一次。题目保证至少有 1 个坏键。

输入样例:
7_This_is_a_test
_hs_s_a_es

输出样例:
7TI

想法一:
使用right,real存储输入的正确字符串和残缺字符串,然后从左到右依次比较两个字符串,然后找到残缺的字符,存入数组lost中。
注意:这里的想法是用户只会少输入字符,然后不会多输入一些无关的字符,即假设rightreal要长:
实现:

#include <iostream>
#include <string>
#include <cstring>

using namespace std;

char upper(char lower); // 大写转换
int find2(char c, char* s,int len); // 在字符数组S里找到c
int main() {
	string right,real; // 正确的输入和实际的输入
	cin >> right >> real;
	char lost[85];  // 坏掉的键
	int st1, st2; // right和real的当前位置
	st1 = st2 = 0;
	int cnt = 0; //丢失的字符数
	while (st1 < right.length() && st2 < real.length()) {
		if (right[st1] == real[st2]) {
			st1++; st2++;
		}
		else {
			char c = right[st1++];
			c = upper(c);
			if (find2(c, lost, cnt) == -1) lost[cnt++] = c;
			// 问题:c语言关系运算符只判断逻辑真假。而不是正负
			// 所以这里不能用取非运算!
		}
	}
	while (st1 < right.length()) { // 正确的输入还没有匹配完
		char c = right[st1++];
		c = upper(c);
		if (!find2(c, lost, cnt)) lost[cnt++] = c;
	}
	for (int i = 0; i < cnt; i++) cout << lost[i];

	system("pause");
}
char upper(char lower) {
	if(lower <= 'z' && lower >= 'a') return (lower - 'a' + 'A');
	else return lower;
}
int find2(char c, char* s,int len) {
	int i;
	if (len == 0) return -1;  // 还没有存储丢失字符
	for (i = 0; i < len && s[i] != c; i++);
	if (i == len) return -1;
	else return i;
}

问题记录:
1.这种方法,最后一个测试点过不了;
2.在C语言中,关系运算符中是判断逻辑,而不是正负;即逻辑只有真假,是0即假,非0即真
所以,不能对返回值-1取非将-1看成假,因为负数也会看成是真

想法二:
遍历right,看其每一个字符是否都能在real中找到,而不考虑输入字符的顺序。

#include <iostream>
#include <string>
#include <cstring>

using namespace std;

char upper(char lower); // 大写转换
int find1(char c, string s); // 在字符串s中找c
int find2(char c, char* s,int len); // 在字符数组S里找到c
int main() {
	string right,real; // 正确的输入和实际的输入
	cin >> right >> real;
	char lost[85];  // 坏掉的键
	int cnt = 0;
	for (int i = 0; i < right.length(); i++) {
		if (find1(right[i], real) == -1) { // 丢失
			char c = right[i];
			c = upper(c);
			if (find2(c, lost, cnt) == -1) lost[cnt++] = c;
		}
	}
	for (int i = 0; i < cnt; i++) cout << lost[i];
	cout << endl;

	system("pause");
}
char upper(char lower) {
	if(lower <= 'z' && lower >= 'a') return (lower - 'a' + 'A');
	else return lower;
}
int find1(char c, string s) {
	int i;
	for (i = 0; i < s.length() && s[i] != c; i++);
	if (i == s.length()) return -1;
	else return i;
}
int find2(char c, char* s,int len) {
	int i;
	if (len == 0) return -1;  // 还没有存储丢失字符
	for (i = 0; i < len && s[i] != c; i++);
	if (i == len) return -1;
	else return i;
}

然后就AC了,真的是服了这个打字的人,为什么要多打。O(∩_∩)O

猜你喜欢

转载自blog.csdn.net/Africa_South/article/details/88569819