C++面试题

最近在牛客上刷题,分享一些比较有意思的AC过了的题目哈
1.DNA序列【字符串】


题目描述
一个DNA序列由A/C/G/T四个字母的排列组合组成。
G和C的比例(定义为GC-Ratio)是序列中G和C两个字母的总的出现次数除以总的字母数目(也就是序列长度)。
在基因工程中,这个比例非常重要。因为高的GC-Ratio可能是基因的起始点。

给定一个很长的DNA序列,以及要求的最小子序列长度,研究人员经常会需要在其中找出GC-Ratio最高的子序列。

本题含有多组样例输入。

输入描述:
输入一个string型基因序列,和int型子串的长度

输出描述:
找出GC比例最高的子串,如果有多个输出第一个的子串

示例1
输入
AACTGTGCACGACCTGA
5

输出
GCACG

#include <iostream>
#include <string>

using namespace std;

void Func();


int main()
{
	Func();

	cin.get();
	return 0;
}


void Func()
{
	string str;
	int n;
	while (cin >> str >> n)
	{
		int nIdx(0);
		int nMax_C_G(0);

		const int nSz(str.length());
		for (int i = 0; i <= nSz - n; i++)
		{
			int nCount(0);
			for (int j = i; j < i + n; j++)
			{
				if (str[j] == 'C' || str[j] == 'G')
				{
					nCount++;
				}
			}

			if (nCount > nMax_C_G)
			{
				nIdx = i;
				nMax_C_G = nCount;
			}
		}

		cout << str.substr(nIdx, n) << endl;
	}
}

2.最长回文字符串

题目描述
Catcher是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信.
比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。
比如进行下列变化 ABBA->12ABBA,ABA->ABAKK,123321->51233214 。
因为截获的串太长了,而且存在多种可能的情况(abaaab可看作是aba,或baaab的加密形式),
Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗?

本题含有多组样例输入。

输入描述:
输入一个字符串

输出描述:
返回有效密码串的最大长度

示例1
输入
ABBA

输出
4
#include <iostream>
#include <string>
#include <vector>
using namespace std;

void Func();


int main()
{
	Func();

	return 0;
}


void Func()
{
	string str;
	while (cin >> str)
	{
		const int nLength(str.length());

		if (nLength <= 1) return;
		int maxLen = 0;
		for (int i = 1; i < nLength; i++)
		{
			//寻找以i-1,i为中点偶数长度的回文
			int low = i - 1, high = i;
			while (low >= 0 && high < nLength && str[low] == str[high])
			{
				low--; 
				high++;
			}
			if (high - low - 1 > maxLen)
			{
				maxLen = high - low - 1;
			}
			
			//寻找以i为中心的奇数长度的回文
			low = i - 1; high = i + 1;
			while (low >= 0 && high < nLength && str[low] == str[high])
			{
				low--; high++;
			}
			if (high - low - 1 > maxLen)
			{
				maxLen = high - low - 1;
			}
			
		}

		cout << maxLen << endl;
	}
}

3.两数组合并排序

题目描述
输入n个整数,输出其中最小的k个。

本题有多组输入样例,请使用循环读入,比如while(cin>>)等方式处理
输入描述:
第一行输入两个整数n和k
第二行输入一个整数数组

输出描述:
输出一个从小到大排序的整数数组

示例1
输入
5 2
1 3 5 7 2

输出
1 2
#include <iostream>
#include <string>
#include <map>

using namespace std;

void Func();


int main()
{
	Func();

	cin.get();
	return 0;
}


void Func()
{

	int nTotal(0);
	int nMin(0);
	while (cin >> nTotal >> nMin)
	{
		multimap<int, int> mpp;		//multimap保存多个Key且自动排序

		int input;
		while (nTotal--)
		{
			cin >> input;
			mpp.insert(pair<int, int>(input, input));
		}

		int i(0);
		for (auto it : mpp)
		{
			if (i >= nMin)
			{
				break;
			}
			cout << it.first << ' ';
			i++;
		}
		cout << endl;
	}
}

4.斐波那契兔子

题目描述
有一只兔子,从出生后第3个月起每个月都生一只兔子,小兔子长到第三个月后每个月又生一只兔子,假如兔子都不死,问每个月的兔子总数为多少?

本题有多组数据。

输入描述:
输入int型表示month

输出描述:
输出兔子总数int型

示例
输入
9

输出
34
#include <iostream>
#include <string>
using namespace std;

void Func();

int Calculate(int n);

int main()
{
	Func();

	return 0;
}


void Func()
{
	int nMonth;
	while (cin>>nMonth)
	{
		int nTotalCount = Calculate(nMonth);
		cout << nTotalCount << endl;
	}
}

int Calculate(int n)
{
	return (n == 1 || n == 2) ? 1 : Calculate(n - 1) + Calculate(n - 2);
}

5.逆置字符串单词

题目描述
对字符串中的所有单词进行倒排。

说明:

1、构成单词的字符只有26个大写或小写英文字母;

2、非构成单词的字符均视为单词间隔符;

3、要求倒排后的单词间隔符以一个空格表示;如果原字符串中相邻单词间有多个间隔符时,倒排转换后也只允许出现一个空格间隔符;

4、每个单词最长20个字母;

输入描述:
输入一行以空格来分隔的句子

输出描述:
输出句子的逆序

示例1
输入
I am a student

输出
student a am I
#include <iostream>
#include <string>
using namespace std;

void Func();

int main()
{
	Func();

	return 0;
}

/*
思路很简单:就是头插法,注意输出的字符串首次插入后不应该加空格
*/
void Func()
{
	string str;
	while (getline(cin, str))
	{
		string strOut;
		const int nLength(str.length());

		bool bAddBlankInited(false);//注意输出的字符串首次插入后不应该加空格
		string temp;
		for (int i = 0; i <= nLength; i++)
		{
			if ((str[i] >= 'A'&&str[i] <= 'Z') || (str[i] >= 'a'&&str[i] <= 'z'))
			{
				if (temp.length() >= 20)
				{
					strOut.insert(0, !bAddBlankInited ? temp : temp + " ");
					temp.clear();
					bAddBlankInited = true;
				}
				temp += str[i];
			}
			else
			{
				if (!temp.empty())
				{
					strOut.insert(0, !bAddBlankInited ? temp : temp + " ");
					temp.clear();
					bAddBlankInited = true;
				}
			}
		}

		cout << strOut << endl;
	}
}

6.输出单链表的指定元素

题目描述
输入一个单向链表,输出该链表中倒数第k个结点,链表的倒数第1个结点为链表的尾指针。

链表结点定义如下:

struct ListNode

{

int       m_nKey;

ListNode* m_pNext;

};


正常返回倒数第k个结点指针,异常返回空指针

本题有多组样例输入。


输入描述:
输入说明
1 输入链表结点个数
2 输入链表的值
3 输入k的值

输出描述:
输出一个整数

示例1
输入
8
1 2 3 4 5 6 7 8
4

输出
5

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

struct ListNode
{
	int value;
	ListNode* m_pNext;
	ListNode(int a)
	{
		value = a;
		m_pNext = NULL;
	}
};


void Func();//纯属为AC而写
void Func2();

int main()
{
	//Func();

	Func2();

	return 0;
}


void Func()
{
	int n;
	while (cin >> n)
	{
		vector<int> arr;
		int input;
		while (n--)
		{
			cin >> input;
			arr.push_back(input);
		}
		int nIndex(0);
		cin >> nIndex;
		if (nIndex > 0 && nIndex < arr.size())
		{
			cout << arr[arr.size() - nIndex] << endl;
		}
		else
		{
			cout << 0 << endl;
		}
	}
}


void Func2()
{
	int n;
	while (cin >> n)
	{
		int nCOunt(n);

		int val;
		ListNode* head = new ListNode(0);
		ListNode* p = head;

		while (n--)
		{
			cin >> val;
			ListNode* q = new ListNode(val);
			p->m_pNext = q;
			p = p->m_pNext;
		}

		int pos(0);
		cin >> pos;
		if (pos > 0 && pos <= nCOunt)
		{
			ListNode* temp = head;
			for (int i = 0; i <= nCOunt - pos; i++)
			{
				temp = temp->m_pNext;
			}
			cout << temp->value << endl;
		}
		else
		{
			cout << 0 << endl;
		}
	}
}

7.字符串加解密

题目描述
1、对输入的字符串进行加解密,并输出。

2、加密方法为:

当内容是英文字母时则用该英文字母的后一个字母替换,同时字母变换大小写,如字母a时则替换为B;字母Z时则替换为a;

当内容是数字时则把该数字加1,如0替换11替换29替换0;

其他字符不做变化。

3、解密方法为加密的逆过程。


本题含有多组样例输入。
输入描述:
输入说明
输入一串要加密的密码
输入一串加过密的密码

输出描述:
输出说明
输出加密后的字符
输出解密后的字符

示例1
输入
abcdefg
BCDEFGH

输出
BCDEFGH
abcdefg
#include <iostream>
#include <string>
using namespace std;


void Func();
string Encrypt(string &str);
string Decrypt(string &str);


int main()
{
	Func();

	return 0;
}


void Func()
{
	string strEncrypt;
	string strDecrypt;

	while (cin >> strEncrypt >> strDecrypt)
	{
		cout << Encrypt(strEncrypt) << endl;
		cout << Decrypt(strDecrypt) << endl;
	}
}


string Encrypt(string &str)
{
	for (auto &it : str)
	{
		if (isalpha(it))
		{
			if (it >= 'A' &&it < 'Z')
			{
				it += ('a' - 'A') + 1;
			}
			else if (it == 'Z')
			{
				it = 'a';
			}
			else if (it >= 'a' && it < 'z')
			{
				it -= ('a' - 'A') - 1;
			}
			else if (it == 'z')
			{
				it = 'A';
			}
		}
		else if (isdigit(it))
		{
			if (it >= '0'&&it < '9')
			{
				it += 1;
			}
			else if (it == '9')
			{
				it = '0';
			}
		}
	}

	return str;
}


string Decrypt(string &str)
{
	for (auto &it : str)
	{
		if (isalpha(it))
		{
			if (it > 'A' &&it <= 'Z')
			{
				it += ('a' - 'A') - 1;
			}
			else if (it == 'A')
			{
				it = 'z';
			}
			else if (it > 'a' && it <= 'z')
			{
				it -= ('a' - 'A') + 1;
			}
			else if (it == 'a')
			{
				it = 'Z';
			}
		}
		else if (isdigit(it))
		{
			if (it > '0'&&it <= '9')
			{
				it -= 1;
			}
			else if (it == '0')
			{
				it = '9';
			}
		}
	}

	return str;
}

手动分割线,晚安

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值