字符串(入门5)

【深基6.例1】自动修正 

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s;
	cin >> s;

	for (char x : s) {
		if (x>='a' && x<='z') {
			cout << char(x - 32);
		}
		else {
			cout << x;
		}
	}
	cout << endl;

	return 0;
}

注意:

那个输出不能直接写x-32,这样输出的是对应大写字母的ASCII码的值

小书童——凯撒密码 

#include <iostream>
#include <string>
using namespace std;
int main()
{
	int n;
	cin >> n;
	string s;
	cin >> s;
	for (int i = 0; i < s.size(); i++) {
		for (int j = 0; j < n; j++) {
			s[i]++;
			if (s[i] > 'z')s[i] = 'a';
		}
	}
	cout << s << endl;


	return 0;
}

注意:

n+x后的ASCII码值有可能大于97+26,所以用这种方法算

[NOIP2008 提高组] 笨小猴 

#include <iostream>
#include <string>
#include <cmath>
using namespace std;

int a[26];

bool fun(int x)
{
	if (x == 0 || x == 1)return false;
	if (x == 2)return true;
	if (x % 2 == 0)return false;
	else {
		for (int i = 3; i < sqrt(x); i++) {
			if (x % i == 0)return false;
		}
	}
	return true;
}

int main()
{
	int maxn = 0, minn = 100;
	string s;
	cin >> s;
	for (char x : s) {
		a[x - 'a']++;
	}
	for (int i = 0; i < 26; i++) {
		if (a[i] > maxn)maxn = a[i];
		if (a[i] < minn && a[i]!=0)minn = a[i];
	}
	if (fun(maxn - minn)) {
		cout << "Lucky Word" << endl;
		cout << maxn - minn << endl;
	}
	else {
		cout << "No Answer" << endl;
		cout << "0" << endl;
	}


	return 0;
}

注意:

sqrt的头文件是cmath,不是algorithm,泪目。

口算练习题 

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

char b[10];

int main()
{
	for (int i = 0; i < 10; i++)b[i] = 'x';
	char a;//运算符
	int n, c, d;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> b;
		if (b[0] >= 'a' && b[0] <= 'c') {
			a = b[0];
			cin >> c >> d;
		}
		else {
			int sum = 0;
			for (int i = 0; b[i] != 'x' && b[i]!='\0'; i++) {
				sum = sum * 10 + (b[i] - '0');
			}
			c = sum;
			cin >> d;
		}
		if (a == 'a') {
			cout << c << "+" << d << "=";
			cout << c + d << endl;
			string temp = to_string(c) + "+" + to_string(d) + "=" + to_string(c + d);
			cout << temp.length() << endl;
		}
		else if (a == 'b') {
			cout << c << "-" << d << "=";
			cout << c - d << endl;
			string temp = to_string(c) + "-" + to_string(d) + "=" + to_string(c - d);
			cout << temp.length() << endl;
		}
		else {
			cout << c << "*" << d << "=";
			cout << c * d << endl;
			string temp = to_string(c) + "*" + to_string(d) + "=" + to_string(c * d);
			cout << temp.length() << endl;
		}
	}


	return 0;
}

注意:

输出格式,以及怎么判断输入的是三个数还是两个数

[NOIP2018 普及组] 标题统计 

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

int main()
{
	string s;

	getline(cin, s);
	int count = 0;
	for (char c : s) {
		if (c != ' ' && c != '\n') {  // 忽略空格和换行符
			count++;
		}
	}

	cout << count << endl;


	return 0;
}

注意:

最好用getline这种可以直接读取一行的函数

【深基6.例6】文字处理软件 

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

int main()
{
	int q;
	cin >> q;
	string s;
	cin >> s;

	for (int i = 0; i < q; i++) {
		int a;
		cin >> a;
		if (a == 1) {
			string ss;
			cin >> ss;
			s = s + ss;
			cout << s << endl;
		}
		else if (a == 2) {
			int b, c;
			cin >> b >> c;
			string ss = s.substr(b, c);
			s = ss;
			cout << s << endl;
		}
		else if (a == 3) {
			int b;
			string ss;
			cin >> b >> ss;
			s.insert(b, ss);
			cout << s << endl;
		}
		else if (a == 4) {
			string ss;
			cin >> ss;
			if (s.find(ss) < s.length()) {
				cout << s.find(ss) << endl;
			}
			else {
				cout << "-1" << endl;
			}
		}
	}


	return 0;
}

[NOIP2011 普及组] 统计单词数 

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

int main()
{
	string a, b;
	getline(cin, a);
	getline(cin, b);

	//全部转换为小写
	for (int i = 0; i < a.length(); i++) {
		a[i] = tolower(a[i]);
	}
	for (int i = 0; i < b.length(); i++) {
		b[i] = tolower(b[i]);
	}

	a = " " + a + " ";
	b = " " + b + " ";

	if (b.find(a)==string::npos) {
		cout << -1 << endl;
	}
	else {
		int alpha = b.find(a);
		int beta = b.find(a);
		int count = 0;
		while (beta != string::npos) {
			count++;
			beta = b.find(a, beta + 1);
		}
		cout << count << " " << alpha << endl;
	}
	

	return 0;
}

注意:

(参考大佬)

后面把a,b前后都加上了空格,是为了避免找到一个单词中出现了a也计算进去了

要用getline去获取a,b,因为直接cin>>a的话,遇到空格就停止了。

手机 

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

int main()
{
	string s;
	getline(cin, s);
	int count = 0;
	for (int i = 0; i < s.length(); i++) {
		if (s[i]=='a' || s[i]=='d' || s[i]=='g'
			|| s[i]=='j' || s[i]=='m'
			|| s[i]=='p' || s[i]=='t' 
			|| s[i]=='w') {
			count++;
		}
		else if (s[i] == 'b' || s[i] == 'e' || s[i] == 'h'
			|| s[i] == 'k' || s[i] == 'n'
			|| s[i] == 'q' || s[i] == 'u'
			|| s[i] == 'x') {
			count += 2;
		}
		else if (s[i] == 'c' || s[i] == 'f' || s[i] == 'i'
			|| s[i] == 'l' || s[i] == 'o'
			|| s[i] == 'r' || s[i] == 'v'
			|| s[i] == 'y') {
			count += 3;
		}
		else if (s[i] == 's' || s[i] == 'z') {
			count += 4;
		}
		else if (s[i] == ' ') {
			count++;
		}
	}
	cout << count << endl;

	return 0;
}

小果的键盘 

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

int main()
{
	int n;
	cin >> n;
	string s;
	cin >> s;
	if (n == 1)cout << 0 << endl;
	else {
		int count = 0;
		for (int i = 0; i < s.length() - 1; i++) {
			if (s[i] == 'V' && s[i + 1] == 'K') {
				count++;
				s[i] = 'X';
				s[i + 1] = 'X';
			}
		}
		for (int i = 0; i < s.length(); i++) {
			if (s[i] != 'X' && s[i] == s[i+1]) {
				count++;
				break;
			}
		}
		cout << count << endl;
	}

	return 0;
}

注意:

1,第一次for循环找到VK后,需要把对应的s[i]改为X,避免后面循环的时候误算进去

2,第二次for循环的时候,只判断s[i]==s[i-1]的时候就可以了,不用分开判断s[i+1]=='V'和=='K'的时候

3,循环的终止条件要注意,不要越界

单词覆盖还原 

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

int main() 
{
	string s;
	cin >> s;
	int b = 0, g = 0;
	s = s + "   ";
	for (int i = 0; i <= s.length() - 3; i++) {
		if (s[i] == 'b' || s[i + 1] == 'o' || s[i + 2] == 'y') {
			b++;
		}
		if (s[i] == 'g' || s[i + 1] == 'i' || s[i + 2] == 'r' || s[i + 3] == 'l') {
			g++;
		}
	}
	cout << b << endl << g << endl;

	return 0;
}

注意:

for循环的终止条件,length-3,但是这样几就需要再s后面先加上三个空格

数字反转(升级版) 

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

int main() 
{
	string s;
	cin >> s;
	char p = 0;//符号位
	int count = 0;
	for (int i = 0; i < s.length(); i++) {
		if (s[i] >= '0' && s[i] <= '9') {
			count++;//记录第一个数的长度
		}
		else {
			//遇到符号位
			p = s[i];
			break;
		}
	}
	int x = count;
	count--;
	//去除多余的前面的0,其实就是从后往前的排除0
	while (s[count] == '0' && count > 0)count--;
	for (int i = count; i >= 0; i--) {
		cout << s[i];
	}
	if (p == 0)return 0;//无符号
	else {
		if (p == '%') {
			cout << p << endl;
			return 0;
		}
		else {
			cout << p;
		}
	}
	int m = s.length() - 1;
	//去除末尾的0
	while (s[x + 1] == '0' && x < m - 1)x++;
	//去除前面的0
	while (s[m] == '0' && m > x + 1)m--;
	for (int i = m; i > x; i--) {
		cout << s[i];
	}


	return 0;
}

注意:

去除多余的0,不仅可以在翻转之后去除,也可以在翻转以前去除,我之前一直想怎么在反转了以后再去除,就有点麻烦,而且自己也绕晕了,后面参考大佬的代码后才明白,囧

还有一个点我要改的是:习惯性在输出后面加上endl换行,导致我有一部分的测试数据过不了,发现是我在输出符号之后直接换行了。

斯诺登的密码 

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

string a[30] = { "","one","two","three","four","five","six","seven",
"eight","nine","ten","elven","twelve","thirteen","fourteen","fifteen",
"sixteen","seventeen","eighteen","nineteen","twenty","a","both",
"another","first","second","third" };
int b[30] = { 0,1,4,9,16,25,36,49,64,81,0,21,44,69,96,25,56,89,24,61,0,
1,4,1,1,4,9 };
int k = 0;
int c[10];

int main() 
{
	for (int i = 0; i < 6; i++) {
		string s;
		cin >> s;
		for (int j = 1; j <= 26; j++) {
			if (s == a[j]) {
				c[++k] = b[j];
				break;
			}
		}
	}
    if (k == 0) {
    	cout << 0 << endl;
    	return 0;
    }
	sort(c + 1, c + k + 1);
	for (int i = 1; i <= k; i++) {
		if (i != 1 && c[i] < 10)cout << 0;
		cout << c[i];
	}
	cout << endl;


	return 0;
}

注意:

在循环输入完所有单词之后,一定要记得先判断k是否为0,不为0的时候才需要进行下面的计算;

当小于10的数字不是第一个的时候需要补0

[USACO1.1] 你的飞碟在这儿 Your Ride Is Here 

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


int main() 
{
	string a, b;
	getline(cin, a);
	getline(cin, b);

	int sumA = 1;
	for (int i = 0; i < a.length(); i++) {
		sumA *= (a[i] - 'A' + 1);
	}
	sumA = sumA % 47;

	int sumB = 1;
	for (int i = 0; i < b.length(); i++) {
		sumB *= (b[i] - 'A' + 1);
	}
	sumB = sumB % 47;

	if (sumA == sumB)cout << "GO" << endl;
	else cout << "STAY" << endl;

	return 0;
}

语句解析 

#include <iostream>
#include <string>
#include <cstdio>
using namespace std;

int a[3];
char s1,s2;

int main() 
{
	while (scanf("%c:=%c;",&s1,&s2) == 2) {
		if (s2 >= '0' && s2 <= '9') {
			a[s1 - 'a'] = s2 - '0';
		}
		else {
			a[s1 - 'a'] = a[s2 - 'a'];
		}
	}
	cout << a[0] << " " << a[1] << " " << a[2] << endl;

	return 0;
}

垂直柱状图 

#include <iostream>
#include <string>

using namespace std;
string s1, s2, s3, s4;
int maxn = 0;
int a[30];
char b[110][30];//最后输出的数组

void fun(string &s) {
	for (int i = 0; i < s.length(); i++) {
		if (s[i] >= 'A' && s[i] <= 'Z') {
			a[s[i] - 'A' + 1]++;
		}
	}
}

int main()
{
	getline(cin, s1);
	getline(cin, s2);
	getline(cin, s3);
	getline(cin, s4);

	fun(s1);
	fun(s2);
	fun(s3);
	fun(s4);

	for (int i = 1; i <= 26; i++) {
		maxn = max(maxn, a[i]);
	}

	for (int i = 1; i <= 26; i++) {
		for (int j = maxn; j >= maxn - a[i] + 1; j--) {
			b[j][i] = '*';
		}
		for (int j = maxn - a[i]; j >= 1; j--) {
			b[j][i] = ' ';
		}
		b[maxn + 1][i] = 1 + 'A' - 1;
	}

	for (int i = 1; i <= maxn; i++) {
		for (int j = 1; j <= 51; j++) {
			if (j % 2 == 0) {
				cout << " ";
				continue;
			}
			cout << b[i][j / 2 + 1];
		}
		cout << endl;
	}


	return 0;
}

注意:

最重要的思想就是把这个柱状图变成一个数组,没有输出的地方就是空格

然后输出的时候也是从第一行开始一行一行输出,理清楚这两点就好理解了