字符串问题-其五_1

替换字符串中连续出现的制定字符串

题目

给定三个字符串str、from和to,把str中所有from的子串全部替换成to字符串,对连续出现from的部分要求只替换成一个to字符串,返回最终的结果字符串。

代码

参考书中将所有from的字符串替换成0,随后将所有的0替换成一个to字符串,具体分析见原书。

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

void clear(char* s, int end, int len)
{
	while (len-- != 0)
		s[end--] = 0;
}

string replace(string str, string from, string to)
{
	if (str.size() < 1 || from.size() < 1 || str == "" || from == "")
		return str;
	int lenS = str.size();
	int lenF = from.size();
	char* s = new char[lenS + 1];
	char* f = new char[lenF + 1];
	strcpy(s, str.c_str());
	strcpy(f, from.c_str());
	int match = 0;
	for (int i = 0; i < lenS; i++)
	{
		if (s[i] == f[match++])
		{
			if (match == lenF)
			{
				clear(s, i, lenF);
				match = 0;
			}
		}
		else
			match = 0;
	}
	string res = "";
	string cur = "";
	for (int i = 0; i < lenS; i++)
	{
		if (s[i] != 0)
			cur += s[i];
		if (s[i] == 0 && (i == 0 || s[i - 1] != 0))
		{
			res = res + cur + to;
			cur = "";
		}
	}
	if (cur != "")
		res = res + cur;
	return res;
}

int main()
{
	string str, from, to;
	getline(cin, str);
	getline(cin, from);
	getline(cin, to);
	string res = replace(str, from, to);
	cout << res << endl;
	getchar();
	return 0;
}

字符串的统计字符串

题目

给定一个字符串str,返回str的统计字符串。如“aaabbadddffc”的统计字符串为"a_3_b_2_a_1_d_3_f_2_c_1"。
补充题目:给定一个字符串的统计字符串cstr,再给定一个整数index,返回cstr所代表的原始字符串上的第index个字符。如”a_1_b_100“所代表的原始字符串上的第0个字符是‘a’,第50个字符是’b’。

代码

详细分析可参考原书籍

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

string getCountString(string str)
{
	if (str.size() < 1 || str == "")
		return "";
	int len = str.size();
	string  fir = str.substr(0, 1);
	string res = fir;
	int num = 1;
	for (int i = 1; i < len; i++)
	{
		if (str[i] != str[i - 1])
		{
			res = res + "_" + to_string(num) + "_" + str[i];
			num = 1;
		}
		else
			num++;
	}
	res = res + "_" + to_string(num);
	return res;
}

//补充问题
char getCharAt(string str, int index)
{
	if (str.size() < 1 || str == "")
		return 0;
	int len = str.size();
	char* s = new char[len + 1];
	strcpy(s, str.c_str());
	bool stage = true;
	char cur = 0;
	int num = 0;
	int sum = 0;
	for (int i = 0; i < len; i++)
	{
		if (s[i] == '_')
			stage = !stage;
		else if (stage)
		{
			sum += num;
			if (sum > index)
				return cur;
			num = 0;
			cur = s[i];
		}
		else
			num = num * 10 + s[i] - '0';
	}
	return sum + num > index ? cur : 0;
}

int main()
{
	string str;
	getline(cin, str);
	int index;
	cin >> index;
	/*string res = getCountString(str);
	cout << res << endl;*/
	char aa = getCharAt(str, index);
	cout << aa << endl;	
	getchar();
	return 0;
}

判断字符数组中是否所有的字符都只出现过一次

题目

给定一个字符类型数组s[],判断s中是否所有的字符都只出现过一次,请根据以下不同的要求实现两个函数。
1、实现时间复杂度为O(N)的方法
2、在保证额外空间复杂度为O(1)的前提下,请事先时间复杂度尽量低的方法。

代码

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

bool isUnique1(char* s, int len)
{
	if (s == NULL)
		return true;
	int* mp = new int[256];
	for (int i = 0; i < 256; i++)
		mp[i] = 0;
	for (int i = 0; i < len; i++)
	{
		mp[s[i]]++;
	}
	for (int i = 0; i < 256; i++)
	{
		if (mp[i] > 1)
			return false;
	}
	return true;
}

//堆排序后判断是否unique
void swap(char* &s, int index1, int index2)
{
	char tmp = s[index1];
	s[index1] = s[index2];
	s[index2] = tmp;
}

void heapInsert(char* s, int i)
{
	int parent = 0;
	while (i != 0)
	{
		parent = (i - 1) / 2;
		if (s[parent] < s[i])
		{
			swap(s, parent, i);
			i = parent;
		}
		else
			break;
	}
}

void heapify(char* s, int i, int size)
{
	int left = i * 2 + 1;
	int right = i * 2 + 2;
	int largest = i;
	while (left < size)
	{
		if (s[left] > s[i])
			largest = left;
		if (right < size && s[right] > s[largest])
			largest = right;
		if (largest != i)
			swap(s, largest, i);
		else
			break;
		i = largest;
		left = i * 2 + 1;
		right = i * 2 + 2;
	}
}

void heapSort(char* s, int len)
{
	for (int i = 0; i < len; i++)
		heapInsert(s, i);
	for (int i = len - 1; i > 0; i--)
	{
		swap(s, 0, i);
		heapify(s, 0, i);
	}
}
bool isUnique2(char* s, int len)
{
	if (s == NULL)
		return true;
	heapSort(s, len);
	for (int i = 1; i < len; i++)
	{
		if (s[i] == s[i - 1])
			return false;
	}
	return true;
}

int main()
{
	int len;
	cin >> len;
	char* in = new char[len + 1];
	for (int i = 0; i < len; i++)
		cin >> in[i];
	//bool res = isUnique1(in, len);
	bool res = isUnique2(in, len);
	if (res)
		cout << "The array is unique!" << endl;
	else
		cout << "Not unique!" << endl;
	getchar();
	return 0;
}

在有序但含有空的数组中查找字符串

题目

给定一个字符串数组str[],在str中有些位置为NULL,但在不为NULL的位置上,其字符串是按照字典顺序由小到大一次出现的。再给定一个字符串s,请返回s在str中出现的最左的位置。

代码

尽最大可能使用二分查找

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

int getIndex(string strs, string str)
{
	if (strs == "" || strs.size() < 1 || str == "")
		return -1;
	int len = strs.size();
	char* s = new char[len + 1];
	strcpy(s, strs.c_str());
	int res = -1;
	int left = 0;
	int right = len - 1;
	int mid = 0;
	int i = 0;
	int lenS = str.size();
	char* strc = new char[len + 1];
	strcpy(strc, str.c_str());
	while (left <= right)
	{
		mid = (left + right) / 2;
		if (s[mid] != NULL && s[mid] == *strc)
		{
			res = mid;
			right = mid - 1;
		}
		else if (s[mid] != NULL)
		{
			if (s[mid] < *strc)
				left = mid + 1;
			else
				right = mid - 1;
		}
		else
		{
			i = mid;
			while (s[i] == NULL && --i >= left)
				;
			if (i < left || s[i] < *strc)
				left = mid + 1;
			else
			{
				res = s[i] == *strc ? i : res;
				right = i - 1;
			}
		}
	}
	return res;
}

int main()
{
	string strs, str;
	getline(cin, strs);
	getline(cin, str);
	int res = getIndex(strs, str);
	cout << res << endl;
	getchar();
	return 0;
}

字符串的调整和替换

输出有点问题,于是暂时没有测试用例,也不把代码拿出来出丑了,有时间再改改。
具体可参考原书籍或者剑指offer。

翻转字符串

题目

给定一个字符类型的数组s,请在单词间做逆序调整。只要做到单词顺序逆序即可,对空格的位置没有特殊要求。
补充题目:给定一个字符类型的数组s和一个整数size,请把大小为size的左半区整体移动到右半区,右半区整体移动到左边。

代码

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

void reverse(char* &s, int start, int end)
{
	char tmp = 0;
	while (start < end)
	{
		tmp = s[start];
		s[start] = s[end];
		s[end] = tmp;
		start++;
		end--;
	}
}

void rotateWord(char* s, int len)
{
	if (s == NULL || len < 1)
		return;
	reverse(s, 0, len - 1);
	int l = -1;
	int r = -1;
	for (int i = 0; i < len; i++)
	{
		if (s[i] != ' ')
		{
			l = i == 0 || s[i - 1] == ' ' ? i : l;
			r = i == len - 1 || s[i + 1] == ' ' ? i : r;
		}
		if (l != -1 && r != -1)
		{
			reverse(s, l, r);
			l = -1;
			r = -1;
		}
	}
}

//补充问题:按照一定的长度来旋转字符串
void rotateSize(char* s, int len, int size)
{
	if (s == NULL || size <= 0 || size > len)
		return;
	reverse(s, 0, size - 1);
	reverse(s, size, len - 1);
	reverse(s, 0, len - 1);
}

int main()
{
	string s;
	getline(cin, s);
	int len = s.size();
	char* str = new char[len + 1];
	strcpy(str, s.c_str());
	rotateWord(str, len);
	for (int i = 0; i < len; i++)
		cout << str[i];
	cout << endl;
	getchar();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值